UIAlertView UIActionSheet UIAlertController统一封装

前言

我们都知道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 

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 () 

@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 0) {
        for (NSInteger i = 0; i

使用方法

 [[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 UIAlertController统一封装)