IOS 自定义控件之UIAlertview

原创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下载链接

时间: 2024-10-14 12:18:40

IOS 自定义控件之UIAlertview的相关文章

IOS开发之UIAlertView与UIAlertController的详尽用法说明

本文将从四个方面对IOS开发中UIAlertView与UIAlertController的用法进行讲解: 一.UIAlertView与UIAlertController是什么东东? 二.我们为什么要用UIAlertView或UIAlertController? 三.如何使用UIAlertView和UIAlertController? 四.阅读提醒. 一.UIAlertView与UIAlertController是什么东东? 一句话,在所有移动应用中,出现的提示窗一般都由UIAlertView或U

IOS自定义控件学习

IOS自定义控件 参考:http://www.oschina.net/question/262659_141737 基本概念 UIView控件只是一个矩形的空白区域,并没有任何内容.iOS应用的其他UI控件都继承了UIView,这些UI控件都是在UIView提供的空白区域上绘制外观.也就是 UIView是所有控件的基类,自定义控件要从这里派生,实现自己的绘制. 重写的方法 initWithFrame 初始化方法. initWithCoder::程序通过在nib文件中加载完该控件后会自动调用该方法

iOS 自定义控件开发

工作需要,最近在进行iOS方面的图表工作.找了很多第三方库都无法实现效果,所以决定自己写一个控件. #0 目标 希望可以写一个通用的图表控件(仅针对此项目),虽然开发难度增大,但是可以学习到很多知识.并且控件使用简单,可以自适应大小,支持屏幕旋转. #1 准备工作 网上各种查资料 研究了一下系统自带控件,全部基于UIView 开发过程中使用storyboard,在页面中加入一个View来控制大小,自定义控件放入此view中并且填充满,让程序可以自适应屏幕尺寸. #2 开始自定义 创建自定义控件,

iOS自定义控件教程:制作一个可重用的旋钮

当你的APP需要一些新功能时,自定义UI控件会十分有用,尤其是这些自定义控件可以在其他APP里面很好的重用.Colin Eberhart写过一篇很棒的介绍自定义UI控件的教程.这个教程涉及的是一个继承自UISlider类的自定义控件的生成:该控件的功能是给定一个(滑动)范围供(用户滑动)选择,并返回一个(与滑动位置相对应的)固定值. 本篇基于iOS 7的自定义UI教程在Colin Eberhart那篇的基础上更深入一步:受调音台旋钮的启发,这里介绍如何制作一个功能类似UISlider的圆形旋转控

iOS 8 中 UIAlertView 和 UIActionSheet 河里去了?

太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:太阳火神的漂亮人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS.Android.Html5.Arduino.pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 弃用了! 如今得用 UIAlertController 了. 使用两个样式来相应这两个控件: UIAlertView - UIAlertContr

iOS 自定义控件

关于UIToolbar,UINavigationController,UINavigationBar,UIBarButtonItem在ios7的使用的简单的介绍,经过搜索资料做了如下的一些汇集 ----------------------------UIBarButtonItem---------------------------- 1:  UIBarButtonItem 隐藏的方式 [self.btnPunctuation setWidth:0]; 2:  UIBarButtonItem 获

IOS 自定义控件之UIActivityIndicatorView

原创blog,转载请注明出处 blog.csdn.net/hello_hwc 前言 这个系列的本身不是为了写一些东西让读者拿过去就直接可以用的.过段时间我会在github上传一些拿去就可以用的.这个系列的本身是希望抛砖引玉,提供一些自定义控件的思路. 本文的内容 阐述了实现自定义UIActivityIndicator的过程 希望通过本文,读者能够学会 CAShapeLayer的简单使用 CAGradientLayer的简单使用 自定义控件的一些思路 一 demo效果 二 实现的过程 用_shap

IOS 自定义控件之-显示下载过程的ImageView

原创Blog,转载请注明出处 blog.csdn.net/hello_hwc 前言:这个系列的目的是为了提供一些思路,在Demo的过程中让读者学会一些自定义控件的思路,所以不适宜太复杂.当然,仅仅是抛砖引玉.这个控件我会上传Github,由于最近一直在搞IOT的应用,所以没时间把进行完善,有时间了我会把这个控件完善了,让读者那去直接就可以用. 完善好了我会更新下博客 Demo效果,支持两种显示过程的方式,沿着border绘制一圈和frame逐渐填充. 思路 NSURLSessionDataTas

iOS 自定义控件 progressView(环形进度条)

转帖:http://blog.csdn.net/xiangzhang321/article/details/42688133 之前做项目的时候有用到环形进度条,先是在网上找了一下第三方控件,发现好用是好用,就是东西太多了,有点复杂,还不如自己写一个简单点适合自己用的. 先把自定义控件的效果图贴出来.     其实我写的这个控件很简单.索性就直接把源码贴出来吧. .h文件的内容就是一些声明 #import <UIKit/UIKit.h> @interface ProgressView : UIV