码迷,mamicode.com
首页 > 移动开发 > 详细

IOS 自定义控件之UIAlertview

时间:2015-02-18 18:50:37      阅读:386      评论:0      收藏:0      [点我收藏+]

标签:ios   自定义   alertview   

原创Blog,转载请注明出处
blog.csdn.net/hello_hwc


前言:这个系列的目的是写一些自定义控件的思路,并不是拿来就可以用的控件,想要直接用的控件库,去github上有的是。这个系列希望抛砖引玉,能够让读者学会如何去自定义控件,授之以渔总比授之以鱼强。

本文的内容

  • demo展示以及说明
  • 如何自定义一个alertview

希望通过本文,读者能够学到

  • 自定义控件的UI布局
  • 自定义控件如何用代理传递事件
  • UIDynamic Animation
    以及UIKit角度的Animation的使用
  • 熟悉面相接口编程的思想。

一 Demo展示
我的习惯是每讲解一些原理,都会写个demo。这个也不例外。
demo的gif如下,用代理的方式传递点击OK或者cancel的事件。
技术分享
二 实现过程

2.1 接口设计
这里仅仅声明了一个初始化方法,一个show方法,以及声明了一个代理,用代理来传值。如果想要自己写一个库的话,API要设计的更完善一些,这里仅仅是为了demo,不搞得那么复杂。

@protocol WCALertviewDelegate<NSObject>
@optional
-(void)didClickButtonAtIndex:(NSUInteger)index;

@end

@interface WCAlertview : UIView
@property (weak,nonatomic) id<WCALertviewDelegate> delegate;
-(instancetype)initWithTitle:(NSString *) title Image:(UIImage *)image CancelButton:(NSString *)cancelButton OkButton:(NSString *)okButton;
- (void)show;
@end

2.2 思考下如何模态的展示Alertview
可以把当前的view作为subview添加到keyWindow,并且设计一个backgroundview,让其的背景色为黑色,透明度为0.4,这就形成了模态展示。
同时,要为backgroundview添加tap手势,让其点击的时候,能够让alertview消失。然后,用一个UIView作为实际展示alertview的实体。所以,层次关系如下
WCAlertview包括backgroubdview以及alertview实体,alertview实体包括图片,title,button等。
为了用UIDynamic Animation,要保存一个Animator的属性。
所以,私有属性应该包括这些

@property (strong,nonatomic)UIDynamicAnimator * animator;
@property (strong,nonatomic)UIView * alertview;
@property (strong,nonatomic)UIView * backgroundview;
@property (strong,nonatomic)NSString * title;
@property (strong,nonatomic)NSString * cancelButtonTitle;
@property (strong,nonatomic)NSString * okButtonTitle;
@property (strong,nonatomic)UIImage * image;

backgroundview实现如下

self.backgroundview = [[UIView alloc] initWithFrame:[[UIApplication sharedApplication] keyWindow].frame];
    self.backgroundview.backgroundColor = [UIColor blackColor];
    self.backgroundview.alpha = 0.4;
    [self addSubview:self.backgroundview];

    UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(click:)];
    [self.backgroundview addGestureRecognizer:tap];

tap的响应函数

-(void)click:(UITapGestureRecognizer *)sender{
    CGPoint tapLocation = [sender locationInView:self.backgroundview];
    CGRect alertFrame = self.alertview.frame;
    if (!CGRectContainsPoint(alertFrame, tapLocation)) {
        [self dismiss];
    }
}

这里的dismiss是让整个WCAlertview消失,注意,要判断点击的点是否在alertview实体内,如果不在,才应该dismiss
dismiss采用UIView的动画

-(void)dismiss{
    [self.animator removeAllBehaviors];
    [UIView animateWithDuration:0.7 animations:^{
        self.alpha = 0.0;
        CGAffineTransform rotate = CGAffineTransformMakeRotation(0.9 * M_PI);
        CGAffineTransform scale = CGAffineTransformMakeScale(0.1, 0.1);
        self.alertview.transform = CGAffineTransformConcat(rotate, scale);
    } completion:^(BOOL finished) {
        [self removeFromSuperview];
         self.alertview = nil;
    }];

}

2.3 设计Alertview的实体
简单的UI控件堆砌

self.alertview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, alertviewWidth, 250)];
    self.alertview.layer.cornerRadius = 17;
    UIView * keywindow = [[UIApplication sharedApplication] keyWindow];
    self.alertview.center = CGPointMake(CGRectGetMidX(keywindow.frame), -CGRectGetMidY(keywindow.frame));
    self.alertview.backgroundColor = [UIColor whiteColor];
    self.alertview.clipsToBounds = YES;

    [self addSubview:self.alertview];


    UILabel * titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,0,alertviewWidth,titleHeight)];
    titleLabel.text = self.title;
    titleLabel.textAlignment = NSTextAlignmentCenter;
    [self.alertview addSubview:titleLabel];

    UIImageView * imageview = [[UIImageView alloc] initWithFrame:CGRectMake(0,titleHeight, alertviewWidth,imageviewHeight)];
    imageview.contentMode = UIViewContentModeScaleToFill;
    imageview.image = self.image;
    imageview.layer.borderColor = [UIColor lightGrayColor].CGColor;
    imageview.layer.borderWidth = 0.5;
    [self.alertview addSubview:imageview];

    CGRect cancelButtonFrame = CGRectMake(0, titleHeight + imageviewHeight,alertviewWidth,buttonHeight);
    if (self.okButtonTitle.length != 0 && self.okButtonTitle !=nil) {
        cancelButtonFrame = CGRectMake(alertviewWidth / 2 ,titleHeight + imageviewHeight, alertviewWidth/2,buttonHeight);
        CGRect okButtonFrame = CGRectMake(0,titleHeight + imageviewHeight, alertviewWidth/2,buttonHeight);
        UIButton * okButton = [self createButtonWithFrame:okButtonFrame Title:self.okButtonTitle];
        okButton.tag = 2;
        [self.alertview addSubview:okButton];

    }
    UIButton * cancelButton = [self createButtonWithFrame:cancelButtonFrame Title:self.cancelButtonTitle];
    cancelButton.tag = 1;
    [self.alertview addSubview:cancelButton];

讲解几点

  • 给button设计tag是为了区分点击了哪个button
  • 由于本demo支持仅有一个cancel button,所以,在初始化的时候要判断几个button来进行frame的调整
  • cancelButton和OKbutton有很多一致的地方,所以用一个函数来创建,避免代码重复。
-(UIButton *)createButtonWithFrame:(CGRect)frame Title:(NSString *)title
{
    UIButton * button = [[UIButton alloc] initWithFrame:frame];
    button.titleLabel.textAlignment = NSTextAlignmentCenter;
    [button setTitle:title forState:UIControlStateNormal];
    [button setTitleColor:[UIColor blueColor]forState:UIControlStateNormal];
    button.titleLabel.textColor = [UIColor blueColor];
    button.titleLabel.textAlignment = NSTextAlignmentCenter;
    button.layer.borderWidth = 0.5;
    button.layer.borderColor = [UIColor lightGrayColor].CGColor;
    [button addTarget:self action:@selector(clickButton:) forControlEvents:UIControlEventTouchUpInside];
    [button setShowsTouchWhenHighlighted:YES];
    return button;
}

2.4 API实现

  • 用snap的dynamic animation来让整个view出现
  • 初始化的函数中,只是需要把值传递给自己的属性
- (void)show {
    UIView * keywindow = [[UIApplication sharedApplication] keyWindow];
    [keywindow addSubview:self];
    self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self];
    UISnapBehavior * sanp = [[UISnapBehavior alloc] initWithItem:self.alertview snapToPoint:self.center];
    sanp.damping = 0.7;
    [self.animator addBehavior:sanp];
}

-(instancetype)initWithTitle:(NSString *) title
                       Image:(UIImage *)image
                CancelButton:(NSString *)cancelButton
                    OkButton:(NSString *)okButton{
    if (self = [super initWithFrame:[[UIApplication sharedApplication] keyWindow].frame]) {
        self.title = title;
        self.image = image;
        self.cancelButtonTitle = cancelButton;
        self.okButtonTitle = okButton;

        [self setUp];
    }
    return self;
}

2.5 用代理传值

-(void)clickButton:(UIButton *)button{
    if ([self.delegate respondsToSelector:@selector(didClickButtonAtIndex:)]) {
        [self.delegate didClickButtonAtIndex:(button.tag -1)];
    }
    [self dismiss];
}

2.6在使用地方

#import "WCAlertview.h"
@interface ViewController ()<WCALertviewDelegate>


@end

@implementation ViewController
- (IBAction)show:(id)sender {
    WCAlertview * alert = [[WCAlertview alloc] initWithTitle:@"Tite"
                                                       Image:[UIImage imageNamed:@"Image1.jpg"]
                                                CancelButton:@"Cancel"
                                                    OkButton:@"OK"];
    alert.delegate = self;
    [alert show];
}
-(void)didClickButtonAtIndex:(NSUInteger)index{
    switch (index) {
        case 0:
            NSLog(@"Click Cancel");
            break;
        case 1:
            NSLog(@"Click OK");

            break;
        default:
            break;
    }
}

最后,附上完整的demo下载,不建议直接拿去用。
CSDN下载链接

IOS 自定义控件之UIAlertview

标签:ios   自定义   alertview   

原文地址:http://blog.csdn.net/hello_hwc/article/details/43877365

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!