iOS封装UIAlertView的delegate回调方式为Bl

作者: TaiXiang | 来源:发表于2016-08-31 21:18 被阅读1051次

    <b><center>将iOS系统UIAlertView的UIAlertViewDelegate改为Block的方式实现<center></b>

    相信很多iOS的开发者在开发中都有过这样的情况,某个需求需要弹出框提示,然后点击提示框的确定或取消就需要跳转页面或者实现相应业务逻辑。这个时候,我遇到大多coder是像下面这样做的:

    @interface ViewController ()<UIAlertViewDelegate>
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"确定删除吗?" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
        [alert show];
    }
    
    #pragma mark - UIAlertViewDelegate
    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    #warning TODO...
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    @end
    

    这样,可以,完美的实现了需求。虽然满足了需求,但是,一个成熟的软件,会随着客户的需求而不断调整代码,会有不同的coder来维护和扩展。当需求是,根据server返回的一个flag值或者什么type的值来判断点击了确定按钮之后的业务逻辑,这个时候,这种方式可能就不是很适合了。通常,最初级的coder可能会在接收到flag的时候写多个if判断,或者switch,然后进行多个弹框,或者为alert加个tag,在引入头文件处声明几个宏#define kFlagA 100 #define kFlagB 101 把这些宏给alert的tag,最后在UIAlertViewDelegate里面根据tag值来做相应的逻辑代码。写完之后测试一把,还不错,完美。过了n久,公司招了一个人来二次开发,改的改需求,然后看到了这里,先是找弹出框show的地方,然后还去理解定义的宏,看了半天,才搞明白对应的aflag该做什么,bflag又是个怎么回事的情况下才会执行... , 通常的coder是不会去改这些方法的,如果是我看到,我会毫不犹豫的花几分钟的时间把这样的代码给替换掉的。 说这些,都是废话。相信真正有这样体验过的coder一定都深有体会。下面就贴出我之前封装的一个UIAlertView,实现了只点击确定的block回调,只点击取消的block回调,以及两个点击都通过block回调,希望对初学iOS者以及理解block、还不知道这种方式的iOSer有所帮助。

    CHAlertView.h

    #import <UIKit/UIKit.h>
    
    /**
    *  @brief 点击回调
    *
    *  @param index 点击的下标
    */
    typedef void (^CHAlertViewClickedWithIndex)(NSInteger index);
    /**
    *  @brief 点击确定按钮回调
    */
    typedef void (^CHAlertViewOkClicked)();
    /**
    *  @brief 点击取消按钮回调
    */
    typedef void (^CHAlertViewCancelClicked)();
    
    /**
    *  @brief 弹出框
    */
    @interface CHAlertView : NSObject
    /**
    *  @brief 弹出提示框,点击返回点击下标
    *
    *  @param title           标题
    *  @param msg             提示信息
    *  @param cancelTitle     取消按钮文字
    *  @param okTitle         确定按钮文字
    *  @param otherTitleArray 其他按钮文字
    *  @param handle          点击回调
    */
    + (void)showCHAlertViewWithTitle:(NSString *)title message:(NSString *)msg cancleButtonTitle:(NSString *)cancelTitle okButtonTitle:(NSString *)okTitle otherButtonTitleArray:(NSArray*)otherTitleArray clickHandle:(CHAlertViewClickedWithIndex) handle;
    /**
    *  @brief 弹出提示框只有确定和取消按钮
    *
    *  @param title             标题
    *  @param msg               提示信息
    *  @param cancelTitle       取消按钮文字
    *  @param okTitle           确定按钮文字
    *  @param okHandle          点击确定回调
    *  @param cancelClickHandle 点击取消回调
    */
    + (void)showCHAlertViewWithTitle:(NSString *)title message:(NSString *)msg cancleButtonTitle:(NSString *)cancelTitle okButtonTitle:(NSString *)okTitle okClickHandle:(CHAlertViewOkClicked)okHandle cancelClickHandle:(CHAlertViewCancelClicked)cancelClickHandle;
    /**
    *  @brief 弹出框,没有回调.
    *
    *  @param title           标题
    *  @param msg             提示信息
    *  @param cancelTitle     取消按钮的文字
    *  @param okTitle         确定按钮的文字
    *  @param otherTitleArray 其他按钮文字
    */
    + (void)showCHAlertViewWithTitle:(NSString *)title message:(NSString *)msg cancleButtonTitle:(NSString *)cancelTitle okButtonTitle:(NSString *)okTitle otherButtonTitleArray:(NSArray*)otherTitleArray;
    
    @end
    

    CHAlertView.m (实现文件里面方法都没有写注释,为什么?因为头文件里面已经写的很详细了。)

    #import "CHAlertView.h"
    #import <objc/runtime.h>
    
    const char *KCHAlertViewIndexBlock = "CHAlertViewIndexBlock";
    const char *KCHAlertViewOkBlock = "CHAlertViewOkBlock";
    const char *KCHAlertViewCancelBlock = "CHAlertViewCancelBlock";
    
    @interface UIAlertView(CHAlertView)
    
    @property (nonatomic,copy)CHAlertViewClickedWithIndex indexBlock;
    @property (nonatomic,copy)CHAlertViewOkClicked okBlock;          
    @property (nonatomic,copy)CHAlertViewCancelClicked cancelBlock;  
    
    @end
    
    @implementation UIAlertView(CHAlertView)
    
    - (void)setIndexBlock:(CHAlertViewClickedWithIndex)indexBlock{
        objc_setAssociatedObject(self, KCHAlertViewIndexBlock, indexBlock, OBJC_ASSOCIATION_COPY);
    }
    - (CHAlertViewClickedWithIndex)indexBlock{
        return objc_getAssociatedObject(self, KCHAlertViewIndexBlock);
    }
    
    - (void)setOkBlock:(CHAlertViewOkClicked)okBlock{
        objc_setAssociatedObject(self, KCHAlertViewOkBlock, okBlock, OBJC_ASSOCIATION_COPY);
    }
    - (CHAlertViewOkClicked)okBlock{
        return objc_getAssociatedObject(self, KCHAlertViewOkBlock);
    }
    
    - (void)setCancelBlock:(CHAlertViewCancelClicked)cancelBlock{
        objc_setAssociatedObject(self, KCHAlertViewCancelBlock, cancelBlock, OBJC_ASSOCIATION_COPY);
    }
    -(CHAlertViewCancelClicked)cancelBlock{
        return objc_getAssociatedObject(self, KCHAlertViewCancelBlock);
    }
    
    @end
    
    @interface CHAlertView ()<UIAlertViewDelegate>
    
    @end
    
    @implementation CHAlertView
    
    #pragma mark -
    + (void)showCHAlertViewWithTitle:(NSString *)title message:(NSString *)msg cancleButtonTitle:(NSString *)cancelTitle okButtonTitle:(NSString *)okTitle otherButtonTitleArray:(NSArray*)otherTitleArray clickHandle:(CHAlertViewClickedWithIndex) handle{
        UIAlertView  *alert = [[UIAlertView alloc] initWithTitle:title message:msg delegate:handle ? self : nil cancelButtonTitle:cancelTitle otherButtonTitles:okTitle, nil];
        if (handle) {
            alert.indexBlock = handle;
        }
        for (NSString *otherTitle in otherTitleArray) {
            [alert addButtonWithTitle:otherTitle];
        }
        [alert show];
    }
    
    #pragma mark -
    + (void)showCHAlertViewWithTitle:(NSString *)title message:(NSString *)msg cancleButtonTitle:(NSString *)cancelTitle okButtonTitle:(NSString *)okTitle okClickHandle:(CHAlertViewOkClicked)okHandle cancelClickHandle:(CHAlertViewCancelClicked)cancelClickHandle{
        UIAlertView  *alert = [[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:cancelTitle otherButtonTitles:okTitle,nil];
        if (okHandle) {
            alert.okBlock = okHandle;
        }
        if (cancelTitle) {
            alert.cancelBlock = cancelClickHandle;
        }
        [alert show];
    }
    
    #pragma mark -
    + (void)showCHAlertViewWithTitle:(NSString *)title message:(NSString *)msg cancleButtonTitle:(NSString *)cancelTitle okButtonTitle:(NSString *)okTitle otherButtonTitleArray:(NSArray*)otherTitleArray{
        [self showCHAlertViewWithTitle:title message:msg cancleButtonTitle:cancelTitle okButtonTitle:okTitle otherButtonTitleArray:otherTitleArray clickHandle:nil];
    }
    
    #pragma mark - UIAlertViewDelegate
    + (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
        if (alertView.indexBlock) {
            alertView.indexBlock(buttonIndex);
        }else{
            if (buttonIndex == 0) {//取消
                if (alertView.cancelBlock) {
                    alertView.cancelBlock();
                }
            }else{//确定            
                if (alertView.okBlock) {
                    alertView.okBlock();
                }
            }
        }
    }
    
    @end
    

    调用简单粗暴

    - (void)viewDidLoad {
        [super viewDidLoad];
        
        NSString *strTitle,*strMsg,*strCancel,*strOk;
        strTitle = @"提示";
        strMsg = @"来呀,互相伤害呀!";
        strCancel = @"不了";
        strOk = @"来就来";
        
        [CHAlertView showCHAlertViewWithTitle:strTitle message:strMsg cancleButtonTitle:strCancel okButtonTitle:strOk otherButtonTitleArray:nil];
        
        [CHAlertView showCHAlertViewWithTitle:strTitle message:strMsg cancleButtonTitle:strCancel okButtonTitle:strOk okClickHandle:^{
    #warning TODO...
        } cancelClickHandle:^{
    #warning TODO...
        }];
        
        [CHAlertView showCHCustomAlertViewWithTitle:strTitle message:strMsg cancleButtonTitle:strCancel okButtonTitle:strOk otherButtonTitleArray:nil clickHandle:^(NSInteger index) {
            NSLog(@"%ld",index);
    #warning TODO...
        }];
    }
    

    (为什么要重构?如何实施重构? 如果看到项目中有我本文开篇所用那种弹框方式的,大可封装一个block的弹框方式来对其重构了。)
    没有什么技术含量的干货,欢迎分享,随意使用。

    相关文章

      网友评论

      • violafa:博主问个问题,为什么这个方法一定要+号,-号没反应的。不明白什么原理。-号不是系统的源码吗?怎么你这里需要用+号方法重写它。然后也你这样才有效果。 + (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex

      本文标题:iOS封装UIAlertView的delegate回调方式为Bl

      本文链接:https://www.haomeiwen.com/subject/drkcettx.html