iOS开发-自定制封装SheetView

前言:众所周知,现在的UIAlertView和UISheetView合并组成了UIAlertController。前几天用到了UIAlertController的UIAlertControllerStyleActionSheet类型,才发现如果要展示多条数据的话,要写好长代码,并且每个Action的block内部都要做响应的操作的话就会让代码看起来非常的繁琐且凌乱。在此前提下,小编想到了封装,如果我自己封装一个SheetView,能够用起来不这么繁琐就好了。

原理:只需要创建的时候传入title和message,然后设置一下Action的title,采用代理的方式传入Action的类型,并将Action的事件使用代理传递。

下面给大家详细介绍:

首先,我是创建了一个类继承于NSObject,由于方法参数使用到了UI控件,所以要导入UIKit框架。在.h文件中设置代理协议及方法,并声明相关参数和接口方法。代码如下:

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@protocol RHSheetViewDelegate;
@interface RHSheetView : NSObject

//声明代理
@property (nonatomic, weak) id<RHSheetViewDelegate> delegate;

//Action的title数组
@property (nonatomic, strong) NSArray * actionTitles;

//自定义构造方法
- (instancetype)initWithTitle:(NSString *)title message:(NSString *)message;

//跳转展示方法
- (void)showWithController:(UIViewController *)controller;
@end
//设置代理协议及方法
@protocol RHSheetViewDelegate <NSObject>

@optional   //非必须实现代理方法
//返回Action的样式
- (UIAlertActionStyle)sheetView:(RHSheetView *)sheetView actionStyleAtIndex:(NSInteger)index;

//点击相应的Action之后触发的方法
- (void)sheetView:(RHSheetView *)sheetView didSelectedAtIndex:(NSInteger)index;

@end

然后,在.m文件中声明一个私有的UIAlertController全局对象,实现.h中声明相应的方法及属性的setter方法。代码如下:

#import "RHSheetView.h"

@interface RHSheetView ()

//声明UIAlertController对象
@property (nonatomic, strong) UIAlertController * alert;
@end
@implementation RHSheetView

#pragma mark - public

- (instancetype)initWithTitle:(NSString *)title message:(NSString *)message {
    
    self = [super init];
    
    if (self) {
        
        //构造方法中创建声明的对象
        _alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleActionSheet];
    }
    return self;
}

- (void)showWithController:(UIViewController *)controller {
    
    //在相应的Controller中弹出弹窗
    [controller presentViewController:_alert animated:YES completion:nil];
}

#pragma mark - setter

//重写声明的数组属性的setter方法
- (void)setActionTitles:(NSArray *)actionTitles {

    //对属性赋值
    _actionTitles = actionTitles;

    //for循环创建Action
    for (int i = 0; i < actionTitles.count; i++) {

        //如果通过代理返回了Action的样式,则根据返回的样式设置相应Action的样式
        if ([self.delegate respondsToSelector:@selector(sheetView:actionStyleAtIndex:)]) {
            
            UIAlertActionStyle style = [self.delegate sheetView:self actionStyleAtIndex:i];
            
            UIAlertAction * action = [UIAlertAction actionWithTitle:actionTitles[i] style:style handler:^(UIAlertAction * _Nonnull action) {

                //在此设置Action的点击代理方法
                if ([self.delegate respondsToSelector:@selector(sheetView:didSelectedAtIndex:)]) {
                    
                    [self.delegate sheetView:self didSelectedAtIndex:i];
                }

                 //点击之后返回到当前界面
                [_alert dismissViewControllerAnimated:YES completion:nil];
            }];
            
            [_alert addAction:action];
        }else {

            //如果没有返回Action样式,则默认设置为UIAlertActionStyleDefault

            UIAlertAction * action = [UIAlertAction actionWithTitle:actionTitles[i] style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {

                 //在此设置Action的点击代理方法
                if ([self.delegate respondsToSelector:@selector(sheetView:didSelectedAtIndex:)]) {
                    
                    [self.delegate sheetView:self didSelectedAtIndex:i];
                }

                 //点击之后返回到当前界面
                [_alert dismissViewControllerAnimated:YES completion:nil];
            }];
            
            [_alert addAction:action];
        }
    }
}

OK!到此封装就结束了,接下来就是实际应用了。在应用中无论需要添加多少个Action,我们要写的代码长度都差不多,小编举了个例子具体如下:

#import "ViewController.h"
#import "RHSheetView.h"

@interface ViewController () <RHSheetViewDelegate>

@property (nonatomic, strong) UIButton * btn;

@property (nonatomic, strong) RHSheetView * sheet;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.view.backgroundColor = [UIColor whiteColor];
    
    [self test];
}

//测试创建了一个button
- (void)test {
    
    _btn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 150, 50)];
    
    _btn.center = self.view.center;
    
    _btn.backgroundColor = [UIColor lightGrayColor];
    
    [_btn setTitle:@"选择更改" forState:UIControlStateNormal];
    
    [_btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
    
    [self.view addSubview:_btn];
}

- (void)btnClick:(UIButton *)btn {
    //button点击弹出SheetView
    [self.sheet showWithController:self];
}

//懒加载创建(这个是小编习惯的创建方式)
- (RHSheetView *)sheet {
    
    if (!_sheet) {
        
        _sheet = [[RHSheetView alloc] initWithTitle:@"请选择支付方式" message:@""];
        
        _sheet.delegate = self;
        
        _sheet.actionTitles = @[@"支付宝支付", @"微信支付", @"取消"];
    }
    return _sheet;
}

#pragma mark - 代理方法实现
//返回Action的样式
- (UIAlertActionStyle)sheetView:(RHSheetView *)sheetView actionStyleAtIndex:(NSInteger)index {

    if (index == 0) {
        
        return UIAlertActionStyleDestructive;
    }else if (index == sheetView.actionTitles.count - 1) {
        
        return UIAlertActionStyleCancel;
    }
    
    return UIAlertActionStyleDefault;
}
//Action点击触发的事件
- (void)sheetView:(RHSheetView *)sheetView didSelectedAtIndex:(NSInteger)index {

    if (index < sheetView.actionTitles.count - 1) {
        
        [_btn setTitle:sheetView.actionTitles[index] forState:UIControlStateNormal];
    }
}
@end

在此小编截图了几张给大家看看效果


初始界面.png

弹出SheetView进行选择.png

选择后.png

如果还有什么不清晰的地方,小编做了Demo已上传到GitHub上边,大家可以去下载看看,git下载地址:https://github.com/guorenhao/SheetView.git

最后,还是希望能够帮到有需要的朋友们,愿同是程序猿的我们能够共同学习进步,在开发的道路上越走越远!谢谢!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容