别人的iOS精华UI的实现iOS技术分享

iOS开发-自定制封装SheetView

2016-10-30  本文已影响882人  it_hao528

前言:众所周知,现在的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

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

上一篇 下一篇

猜你喜欢

热点阅读