UIAlertView UIActionSheet UIAler

作者: ivylee_mr | 来源:发表于2017-08-15 15:54 被阅读117次

    前言

    我们都知道UIAlertView UIActionSheet 是iOS 8.0之前的方法,在iOS 8.0之后,苹果公司开始放弃这些方法,采用UIAlertController来制作提醒提示框。

    所以此次的目的主要是将UIAlertView UIActionSheet UIAlertController统一封装,根据用户手机系统版本自动采用UIAlertView UIActionSheet还是 UIAlertController

    这样可以保证你的代码可以跨系统使用。

    具体效果如下:

    未命名.gif

    知识点一:NS_REQUIRES_NIL_TERMINATION

    NS_REQUIRES_NIL_TERMINATION是一个宏,告知编译器 需要一个结尾的参数,告知编译器参数的列表已经到最后一个不要再继续执行下去了。

    该方法总传递的Action Item 和 数组之间的转换为:

    // 读取可变参数里面的titles数组
    
    NSMutableArray *titleArray = [[NSMutableArray alloc] initWithCapacity:0];
    
    va_list list;
    
    if(buttonTitles) {
    
    //1.取得第一个参数的值(即是buttonTitles)
    
    [titleArray addObject:buttonTitles];
    
    //2.从第2个参数开始,依此取得所有参数的值
    
    NSString *otherTitle;
    
    va_start(list, buttonTitles);
    
    while ((otherTitle= va_arg(list, NSString*))) {
    
    [titleArray addObject:otherTitle];
    
    }
    
    va_end(list);
    
    }
    

    知识点二:UIAlertControllerStyleActionSheetUIActionSheet区别

    UIAlertControllerStyleActionSheet支持message
    UIActionSheet是没有message 只有title
    具体大家可以查看各自的初始化方法就知道了。

    这里直接上代码

    .h文件

    //
    //  LeeAlertSheetView.h
    //  FrameWork
    //
    //  Created by LeeMiao on 2017/8/9.
    //  Copyright © 2017年 Limiao. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    
    typedef void(^myAlertSheetViewBlock)(NSInteger buttonTag,NSString *buttonTitle);
    
    static NSInteger const cancelIndex = -1;
    
    @interface LeeAlertSheetView : NSObject
    
    
    
    /**
     单例模式
     @return 单例对象
     */
    +(LeeAlertSheetView *)sharedInstacne;
    
    /**
     *  创建提示框(Alert 可变参数版)
     *
     *  @param title        标题
     *  @param message      提示内容
     *  @param cancelTitle  取消按钮(无操作,为nil则只显示一个按钮)
     *  @param vc           VC iOS8及其以后会用到
     *  @param confirm      点击按钮的回调(取消按钮的Index是cancelIndex -1)
     *  @param buttonTitles 按钮(为nil,默认为"确定",传参数时必须以nil结尾,否则会崩溃)
     */
    - (void)showAlert:(NSString *)title message:(NSString *)message cancelTitle:(NSString *)cancelTitle viewController:(UIViewController *)vc confirm:(myAlertSheetViewBlock)confirm buttonTitles:(NSString *)buttonTitles, ... NS_REQUIRES_NIL_TERMINATION;
    
    /**
     *  创建菜单(Sheet 可变参数版)
     *
     *  @param title        标题
     *  @param message      提示内容
     *  @param cancelTitle  取消按钮(无操作,为nil则只显示一个按钮)
     *  @param vc           VC
     *  @param confirm      点击按钮的回调(取消按钮的Index是cancelIndex -1)
     *  @param buttonTitles 按钮(为nil,默认为"确定",传参数时必须以nil结尾,否则会崩溃)
     */
    - (void)showSheet:(NSString *)title message:(NSString *)message cancelTitle:(NSString *)cancelTitle viewController:(UIViewController *)vc confirm:(myAlertSheetViewBlock)confirm buttonTitles:(NSString *)buttonTitles, ... NS_REQUIRES_NIL_TERMINATION ;
    
    
    @end
    
    

    .m文件

    //
    //  LeeAlertSheetView.m
    //  FrameWork
    //
    //  Created by LeeMiao on 2017/8/9.
    //  Copyright © 2017年 Limiao. All rights reserved.
    //
    
    #import "LeeAlertSheetView.h"
    
    #define RootVC  [[UIApplication sharedApplication] keyWindow].rootViewController
    #define IOS8AndLater [[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0
    
    @interface LeeAlertSheetView () <UIActionSheetDelegate,UIAlertViewDelegate>
    
    @property (nonatomic, copy) myAlertSheetViewBlock block;
    @property (nonatomic,assign) NSInteger selectBtnTag;
    @end
    
    @implementation LeeAlertSheetView
    
    #pragma mark- 对外方法
    +(LeeAlertSheetView *)sharedInstacne{
        static LeeAlertSheetView *instance = nil;
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            instance = [[self alloc] init];
        });
        return instance;
    }
    
    
    -(void)showAlert:(NSString *)title message:(NSString *)message cancelTitle:(NSString *)cancelTitle viewController:(UIViewController *)vc confirm:(myAlertSheetViewBlock)confirm buttonTitles:(NSString *)buttonTitles, ...{
        if (!vc) vc = RootVC;
        
        // 读取可变参数里面的titles数组
        NSMutableArray *titleArray = [[NSMutableArray alloc] initWithCapacity:0];
        va_list list;
        if(buttonTitles) {
            //1.取得第一个参数的值(即是buttonTitles)
            [titleArray addObject:buttonTitles];
            //2.从第2个参数开始,依此取得所有参数的值
            NSString *otherTitle;
            va_start(list, buttonTitles);
            while ((otherTitle= va_arg(list, NSString*))) {
                [titleArray addObject:otherTitle];
            }
            va_end(list);
        }
        
        if (IOS8AndLater) {
            [self lee_showAlertController:title message:message cancelTitle:cancelTitle titleArray:titleArray viewController:vc confirm:confirm];
        }else{
            [self lee_showAlertView:title message:message cancelTitle:cancelTitle viewController:vc confirm:confirm titleArray:titleArray];
        }
        
    
    }
    
    
    -(void)showSheet:(NSString *)title message:(NSString *)message cancelTitle:(NSString *)cancelTitle viewController:(UIViewController *)vc confirm:(myAlertSheetViewBlock)confirm buttonTitles:(NSString *)buttonTitles, ...{
        if (!vc) vc = RootVC;
        // 读取可变参数里面的titles数组
        NSMutableArray *titleArray = [[NSMutableArray alloc] initWithCapacity:0];
        va_list list;
        if(buttonTitles) {
            //1.取得第一个参数的值(即是buttonTitles)
            [titleArray addObject:buttonTitles];
            //2.从第2个参数开始,依此取得所有参数的值
            NSString *otherTitle;
            va_start(list, buttonTitles);
            while ((otherTitle= va_arg(list, NSString*))) {
                [titleArray addObject:otherTitle];
            }
            va_end(list);
        }
        if (IOS8AndLater) {
            [self lee_showSheetAlertController:title message:message cancelTitle:cancelTitle titleArray:titleArray viewController:vc confirm:confirm];
        }else{
            [self lee_showSheetView:title message:message cancelTitle:cancelTitle viewController:vc confirm:confirm titleArray:titleArray];
        }
        
    }
    
    
    
    
    #pragma mark - ----------------内部方法 IOS8 以后------------------
    //UIAlertController(iOS8及其以后)
    - (void)lee_showAlertController:(NSString *)title message:(NSString *)message cancelTitle:(NSString *)cancelTitle titleArray:(NSArray *)titleArray viewController:(UIViewController *)vc
                          confirm:(myAlertSheetViewBlock)confirm {
        
        UIAlertController  *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
        // 下面两行代码 是修改 title颜色和字体的代码
        //    NSAttributedString *attributedMessage = [[NSAttributedString alloc] initWithString:title attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:17.0f], NSForegroundColorAttributeName:UIColorFrom16RGB(0x334455)}];
        //    [alert setValue:attributedMessage forKey:@"attributedTitle"];
        if (cancelTitle) {
            // 取消
            UIAlertAction  *cancelAction = [UIAlertAction actionWithTitle:cancelTitle  style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
                
                if (confirm) {
                    confirm(0, action.title);
                }
                
            }];
            [alert addAction:cancelAction];
        }
        // 确定操作
        if (!titleArray || titleArray.count == 0) {
            UIAlertAction  *confirmAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault  handler:^(UIAlertAction * _Nonnull action) {
                if (confirm)confirm(0,action.title);
            }];
            [alert addAction:confirmAction];
        } else {
            for (NSInteger i = 0; i<titleArray.count; i++) {
                UIAlertAction  *action = [UIAlertAction actionWithTitle:titleArray[i] style:UIAlertActionStyleDefault  handler:^(UIAlertAction * _Nonnull action) {
                    if (confirm)confirm(i,action.title);
                }];
                // [action setValue:UIColorFrom16RGB(0x00AE08) forKey:@"titleTextColor"]; // 此代码 可以修改按钮颜色
                [alert addAction:action];
            }
        }
        [vc presentViewController:alert animated:YES completion:nil];
    }
    
    
    // ActionSheet的封装(iOS8及其以后)
    - (void)lee_showSheetAlertController:(NSString *)title message:(NSString *)message cancelTitle:(NSString *)cancelTitle titleArray:(NSArray *)titleArray viewController:(UIViewController *)vc confirm:(myAlertSheetViewBlock)confirm {
        
        UIAlertController *sheet = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleActionSheet];
        if (!cancelTitle) cancelTitle = @"取消";
        // 取消
        UIAlertAction  *cancelAction = [UIAlertAction actionWithTitle:cancelTitle style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
            if (confirm)confirm(cancelIndex,action.title);
        }];
        
        [sheet addAction:cancelAction];
        if (titleArray.count > 0) {
            for (NSInteger i = 0; i<titleArray.count; i++) {
                UIAlertAction  *action = [UIAlertAction actionWithTitle:titleArray[i] style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                    if (confirm)confirm(i,action.title);
                }];
                [sheet addAction:action];
            }
        }
        
        [vc presentViewController:sheet animated:YES completion:nil];
    }
    
    #pragma mark - ----------------内部方法 IOS8 之前------------------
    //UIAlertView
    -(void)lee_showAlertView:(NSString *)title message:(NSString *)message cancelTitle:(NSString *)cancelTitle viewController:(UIViewController *)vc
                     confirm:(myAlertSheetViewBlock)confirm  titleArray:(NSArray *)titleArray{
        
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:title message:message delegate:self cancelButtonTitle:cancelTitle otherButtonTitles: nil];
    
        if (confirm){
            self.block = confirm;
        }
        
        [titleArray enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            [alert addButtonWithTitle:obj];
        }];
        
        [alert show];
    }
    
    
    -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
        if (self.block) {
            self.block(buttonIndex,[alertView buttonTitleAtIndex:buttonIndex]);
        }
    }
    
    
    //UIActionSheet
    -(void)lee_showSheetView:(NSString *)title message:(NSString *)message cancelTitle:(NSString *)cancelTitle viewController:(UIViewController *)vc
                     confirm:(myAlertSheetViewBlock)confirm  titleArray:(NSArray *)titleArray{
        
        UIActionSheet *sheet = [[UIActionSheet alloc]initWithTitle:title delegate:self cancelButtonTitle:cancelTitle destructiveButtonTitle:nil otherButtonTitles:nil];
        if (confirm){
            self.block = confirm;
        }
        
        [titleArray enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            [sheet addButtonWithTitle:obj];
        }];
        
        [sheet showInView:vc.view];
    }
    
    
    -(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
        if (self.block) {
            self.block(buttonIndex,[actionSheet buttonTitleAtIndex:buttonIndex]);
        }
    }
    
    @end
    
    

    使用方法

     [[LeeAlertSheetView sharedInstacne]showSheet:nil message:nil cancelTitle:@"取消" viewController:self confirm:^(NSInteger buttonTag,NSString *buttonTitle) {
                NSLog(@"%ld-%@",buttonTag,buttonTitle);
               // 你的业务逻辑根据buttonTag,buttonTitle 处理。
            } buttonTitles:@"Hello",@"Lee",@"Miao", nil];
    

    相关文章

      网友评论

        本文标题:UIAlertView UIActionSheet UIAler

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