模仿系统方法自定义UIAlertView的实现和代理

简介: 模仿系统方法自定义UIAlertView的实现和代理

背景是博主偷懒依然用了iOS8后被废弃掉的UIAlertView,然后取消的字体比确定要粗,同时为了统一界面风格,需要把UIAlertView统一换成定制的样子,博主就犯难了,又不想大批量更改代码,怎么办,突然意识到为什么我不能自己写一个类似系统的方法呢,只要整体代码一样,不就可以通过搜索统一修改一下类名就好了么?说干就干,这里贴上代码:

#import <UIKit/UIKit.h>
@class MyAlertView;
@protocol MyAlertDelegate <NSObject>
-(void)alertView:(MyAlertView *)alertView clickedButtonAtIndex:(NSUInteger)buttonIndex;
@end
@interface MyAlertView : UIView
@property (weak,nonatomic) id<MyAlertDelegate>delegate;
-(instancetype)initWithTitle:title message:messge delegate:delegate cancelButtonTitle:cancelTitle otherButtonTitle:otherTitle;
-(void)show;
@end
#import "MyAlertView.h"
#define WIDTH [UIApplication sharedApplication].keyWindow.frame.size.width
#define HEIGHT [UIApplication sharedApplication].keyWindow.frame.size.height
@interface MyAlertView()
@property(nonatomic,strong)UIView *blackView;
@property(nonatomic,strong)UIView *alertBackView;
@property(nonatomic,strong)UILabel *contentLabel;
@property(nonatomic,strong)UIButton *cancelBtn;
@property(nonatomic,strong)UIButton *okBtn;
@property(nonnull,strong)NSString *title;
@property(nonnull,strong)NSString *content;
@property(nonnull,strong)NSString *cancelBtnTitle;
@property(nonnull,strong)NSString *okBtnTitle;
@end
@implementation MyAlertView
-(instancetype)initWithTitle:title message:messge delegate:delegate cancelButtonTitle:cancelTitle otherButtonTitle:otherTitle
{
    if (self=[super initWithFrame:[[UIApplication sharedApplication] keyWindow].frame]) {
        _delegate=delegate;
        _title=title;
        _content=messge;
        _cancelBtnTitle=cancelTitle;
        _okBtnTitle=otherTitle;
        [self setUp];
    }
    return self;
}
-(void)setUp
{
    NSLog(@"%f",WIDTH);
    NSLog(@"%f",HEIGHT);
    //黑色背景
    _blackView=[[UIView alloc] initWithFrame:CGRectMake(0, 0, WIDTH, HEIGHT)];
    _blackView.backgroundColor=[UIColor blackColor];
    _blackView.alpha=0.6;
    [self addSubview:_blackView];
    //弹出框背景
    _alertBackView=[[UIView alloc]initWithFrame:CGRectMake(20, 44, WIDTH-40, 160)];
    _alertBackView.layer.cornerRadius=6;
    _alertBackView.center=CGPointMake(320/2, 568/2);
    _alertBackView.backgroundColor=[UIColor whiteColor];
    [self addSubview:_alertBackView];
    //标题
    UILabel *alertTitle=[[UILabel alloc]initWithFrame:CGRectMake(20, 10, WIDTH-40-40, 20)];
    alertTitle.text=_title;
    alertTitle.textAlignment=NSTextAlignmentCenter;
    alertTitle.textColor=[UIColor colorWithRed:0.31f green:0.31f blue:0.31f alpha:1.00f];
    alertTitle.font=[UIFont systemFontOfSize:15];
    [_alertBackView addSubview:alertTitle];
    //消息内容
    UILabel *message=[[UILabel alloc]initWithFrame:CGRectMake(20, 30, WIDTH-40-40, 60)];
    message.text=_content;
    message.numberOfLines=0;
    message.textAlignment=NSTextAlignmentCenter;
    message.textColor=[UIColor colorWithRed:0.31f green:0.31f blue:0.31f alpha:1.00f];
    message.font=[UIFont systemFontOfSize:15];
    [_alertBackView addSubview:message];
    //    CAKeyframeAnimation * animation;
    //    animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
    //    animation.duration = 0.5;
    //    animation.delegate = self;
    //    animation.removedOnCompletion = YES;
    //    animation.fillMode = kCAFillModeForwards;
    //
    //    NSMutableArray *values = [NSMutableArray array];
    //    [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)]];
    //    [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.1, 1.1, 1.0)]];
    //    [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(0.9, 0.9, 0.9)]];
    //    [values addObject:[NSValue valueWithCATransform3D:CATransform3DMakeScale(1.0, 1.0, 1.0)]];
    //
    //    animation.values = values;
    //    [_alertBackView.layer addAnimation:animation forKey:nil];
    //按钮背景
    UIView *btnBGView=[[UIView alloc]initWithFrame:CGRectMake(0, 100, WIDTH-40, 60)];
    btnBGView.backgroundColor=[UIColor colorWithRed:0.96f green:0.96f blue:0.96f alpha:1.00f];
    [_alertBackView addSubview:btnBGView];
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:btnBGView.bounds byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight cornerRadii:CGSizeMake(3, 3)];
    CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = btnBGView.bounds;
    maskLayer.path = maskPath.CGPath;
    btnBGView.layer.mask = maskLayer;
    if (_cancelBtnTitle==nil||_okBtnTitle==nil) {
        //确定按钮
        _okBtn=[UIButton buttonWithType:UIButtonTypeRoundedRect];
        _okBtn.frame=CGRectMake((WIDTH-40-220)/2, 15, 220, 30);
        _okBtn.titleLabel.font=[UIFont systemFontOfSize:15];
        [_okBtn setTitle:_cancelBtnTitle==nil ? _okBtnTitle:_cancelBtnTitle forState:UIControlStateNormal];
        [_okBtn setBackgroundImage:[UIImage imageNamed:@"login_loginbtn.png"] forState:UIControlStateNormal];
        [_okBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        _okBtn.tag=1;
        [_okBtn addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [btnBGView addSubview:_okBtn];
    }
    else
    {
        //取消按钮
        _cancelBtn=[UIButton buttonWithType:UIButtonTypeRoundedRect];
        _cancelBtn.frame=CGRectMake(25, 15,100, 30);
        _cancelBtn.titleLabel.font=[UIFont systemFontOfSize:15];
        [_cancelBtn setTitle:_cancelBtnTitle forState:UIControlStateNormal];
        [_cancelBtn setBackgroundImage:[UIImage imageNamed:@"detail_alert_left"] forState:UIControlStateNormal];
        [_cancelBtn setTitleColor:[UIColor colorWithRed:0.47f green:0.47f blue:0.47f alpha:1.00f] forState:UIControlStateNormal];
        _cancelBtn.tag=0;
        [_cancelBtn addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [btnBGView addSubview:_cancelBtn];
        //确定按钮
        _okBtn=[UIButton buttonWithType:UIButtonTypeRoundedRect];
        _okBtn.frame=CGRectMake(WIDTH-40-25-100, 15, 100, 30);
        _okBtn.titleLabel.font=[UIFont systemFontOfSize:15];
        [_okBtn setTitle:_okBtnTitle forState:UIControlStateNormal];
        [_okBtn setBackgroundImage:[UIImage imageNamed:@"detail_alert_right"] forState:UIControlStateNormal];
        [_okBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        _okBtn.tag=1;
        [_okBtn addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
        [btnBGView addSubview:_okBtn];
    }
}
-(void)buttonAction:(UIButton *)btn
{
    if ([self.delegate respondsToSelector:@selector(alertView:clickedButtonAtIndex:)]) {
        [self.delegate alertView:self clickedButtonAtIndex:(btn.tag)];
    }
    self.alpha = 0.0;
    [self removeFromSuperview];
    _blackView=nil;
    _alertBackView=nil;
}
-(void)show
{
    UIView * keywindow = [[UIApplication sharedApplication] keyWindow];
    [keywindow addSubview:self];
}

原谅我没写很多注释,不过我觉得大家都能看得懂,我并没有写的很复杂。这里需要注意的问题是,怎么把自己的alert添加到控制器上来显示,添加是简单,可是像系统那样,不在调用时设置frame和利用控制器addSubView怎么实现呢?博主一开始纠结了好久,不过最后算是写出来了,参考的小伙伴要认真看下,还有代理的实现步骤,需要格外注意下哦,代码中注释部分为动画效果,自定义alert弹出时不会像系统的那样直接让当前键盘收回,如果有键盘时触发,键盘有可能会遮挡到当前alert,需要在触发时手动对键盘resignFirstResponder。其他的博主就不详细说明了,代码中有体现。附上github下载地址:https://github.com/codeliu6572/CustomAlertView

目录
相关文章
|
4月前
|
搜索推荐 C++ 索引
C++ Qt开发:QItemDelegate自定义代理组件
在Qt中,`QStyledItemDelegate` 类是用于创建自定义表格视图(如`QTableView`和`QTableWidget`)的委托类,允许你自定义表格中每个单元格的外观和交互。`QStyledItemDelegate` 是`QItemDelegate` 的子类,提供了更现代、更易用的接口。此处我们将实现对`QTableView`表格组件的自定义代理功能,例如默认情况下表格中的缺省代理就是一个编辑框,我们只能够在编辑框内输入数据,而有时我们想选择数据而不是输入,此时就需要重写编辑框实现选择的效果,代理组件常用于个性化定制表格中的字段类型。
37 0
C++ Qt开发:QItemDelegate自定义代理组件
|
开发工具 Android开发
RxBus 一个简易、非反射的Android事件通知库
RxBus 一个简易、非反射的Android事件通知库
699 0
RxBus 一个简易、非反射的Android事件通知库
J3
|
Java
对象只能new吗?傻瓜、海王都是会五六种方式
绝对不是标题党,我真能用五六种方式创建出对象出来,只不过是在 Java 中。 当然,我也绝非海王,这毋庸置疑😛😛😛。
J3
166 0
对象只能new吗?傻瓜、海王都是会五六种方式
|
iOS开发
iOS网络编程之五——请求回执类NSURLResponse属性简介
iOS网络编程之五——请求回执类NSURLResponse属性简介
243 0
|
JSON 资源调度 安全
Chainlink是如何实现“万能插头”的--外部适配器的开发和应用
在以太坊原生语言solidity中调用API可以将链下数据传输至链上智能合约应用。世界各地的开发者可以利用Chainlink的去中心化区块链预言机将链下真实世界的数据和事件接入区块链环境。Chainlink内置的核心适配器可以轻松配置并验证来自任何开放API的数据。
435 0
|
iOS开发 开发者 编译器
iOS开发--通知,代理,KVO的区别,以及通知的多线程问题
1. delegate 当我们第一次编写ios应用时,我们注意到不断的在使用“delegate”,并且贯穿于整个SDK。delegation模式不是IOS特有的模式,而是依赖与你过去拥有的编程背景。针对它的优势以及为什么经常使用到,这种模式可能不是很明显的。
|
C#
WPF 为资源字典 添加事件响应的后台类
原文:WPF 为资源字典 添加事件响应的后台类 前言,有许多同学在写WPF程序时在资源字典里加入了其它控件,但又想写事件来控制这个控件,但是资源字典没有CS文件,不像窗体XAML还有一个后台的CS文件,怎么办呢? 在工作时也遇到了这个问题,现在把它分享出来 比如说我们现在要写一个TabControl控件,在TabItem中有一个关闭按钮或其它按钮,这个按钮要能响应某个事件。
1548 0
|
JSON Android开发 图形学
Unity3D安卓程序中提示窗与常用静态方法封装
Unity3D/安卓封装SDK常用方法 本文提供全流程,中文翻译。Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例) 1 IO ...
1317 0