UIAlertView UIActionSheet UIAlertController統(tǒng)一封裝

前言

我們都知道UIAlertView UIActionSheet 是iOS 8.0之前的方法,在iOS 8.0之后,蘋果公司開始放棄這些方法,采用UIAlertController來制作提醒提示框。

所以此次的目的主要是將UIAlertView UIActionSheet UIAlertController統(tǒng)一封裝,根據(jù)用戶手機(jī)系統(tǒng)版本自動(dòng)采用UIAlertView UIActionSheet還是 UIAlertController。

這樣可以保證你的代碼可以跨系統(tǒng)使用。

具體效果如下:

未命名.gif

知識點(diǎn)一:NS_REQUIRES_NIL_TERMINATION

NS_REQUIRES_NIL_TERMINATION是一個(gè)宏,告知編譯器 需要一個(gè)結(jié)尾的參數(shù),告知編譯器參數(shù)的列表已經(jīng)到最后一個(gè)不要再繼續(xù)執(zhí)行下去了。

該方法總傳遞的Action Item 和 數(shù)組之間的轉(zhuǎn)換為:

// 讀取可變參數(shù)里面的titles數(shù)組

NSMutableArray *titleArray = [[NSMutableArray alloc] initWithCapacity:0];

va_list list;

if(buttonTitles) {

//1.取得第一個(gè)參數(shù)的值(即是buttonTitles)

[titleArray addObject:buttonTitles];

//2.從第2個(gè)參數(shù)開始,依此取得所有參數(shù)的值

NSString *otherTitle;

va_start(list, buttonTitles);

while ((otherTitle= va_arg(list, NSString*))) {

[titleArray addObject:otherTitle];

}

va_end(list);

}

知識點(diǎn)二:UIAlertControllerStyleActionSheetUIActionSheet區(qū)別

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;

/**
 *  創(chuàng)建提示框(Alert 可變參數(shù)版)
 *
 *  @param title        標(biāo)題
 *  @param message      提示內(nèi)容
 *  @param cancelTitle  取消按鈕(無操作,為nil則只顯示一個(gè)按鈕)
 *  @param vc           VC iOS8及其以后會用到
 *  @param confirm      點(diǎn)擊按鈕的回調(diào)(取消按鈕的Index是cancelIndex -1)
 *  @param buttonTitles 按鈕(為nil,默認(rèn)為"確定",傳參數(shù)時(shí)必須以nil結(jié)尾,否則會崩潰)
 */
- (void)showAlert:(NSString *)title message:(NSString *)message cancelTitle:(NSString *)cancelTitle viewController:(UIViewController *)vc confirm:(myAlertSheetViewBlock)confirm buttonTitles:(NSString *)buttonTitles, ... NS_REQUIRES_NIL_TERMINATION;

/**
 *  創(chuàng)建菜單(Sheet 可變參數(shù)版)
 *
 *  @param title        標(biāo)題
 *  @param message      提示內(nèi)容
 *  @param cancelTitle  取消按鈕(無操作,為nil則只顯示一個(gè)按鈕)
 *  @param vc           VC
 *  @param confirm      點(diǎn)擊按鈕的回調(diào)(取消按鈕的Index是cancelIndex -1)
 *  @param buttonTitles 按鈕(為nil,默認(rèn)為"確定",傳參數(shù)時(shí)必須以nil結(jié)尾,否則會崩潰)
 */
- (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;
    
    // 讀取可變參數(shù)里面的titles數(shù)組
    NSMutableArray *titleArray = [[NSMutableArray alloc] initWithCapacity:0];
    va_list list;
    if(buttonTitles) {
        //1.取得第一個(gè)參數(shù)的值(即是buttonTitles)
        [titleArray addObject:buttonTitles];
        //2.從第2個(gè)參數(shù)開始,依此取得所有參數(shù)的值
        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;
    // 讀取可變參數(shù)里面的titles數(shù)組
    NSMutableArray *titleArray = [[NSMutableArray alloc] initWithCapacity:0];
    va_list list;
    if(buttonTitles) {
        //1.取得第一個(gè)參數(shù)的值(即是buttonTitles)
        [titleArray addObject:buttonTitles];
        //2.從第2個(gè)參數(shù)開始,依此取得所有參數(shù)的值
        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 - ----------------內(nèi)部方法 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 - ----------------內(nèi)部方法 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);
           // 你的業(yè)務(wù)邏輯根據(jù)buttonTag,buttonTitle 處理。
        } buttonTitles:@"Hello",@"Lee",@"Miao", nil];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • iOS 8的新特性之一就是讓接口更有適應(yīng)性、更靈活,因此許多視圖控制器的實(shí)現(xiàn)方式發(fā)生了巨大的變化。全新的UIPre...
    烏拉拉zzZ閱讀 939評論 0 2
  • github排名https://github.com/trending,github搜索:https://gith...
    小米君的demo閱讀 4,777評論 2 38
  • 墨棠子閱讀 243評論 8 11
  • 從小到大應(yīng)該就沒注意過冬至,畢竟只是個(gè)節(jié)氣,根本就想不起來也沒人去想,在我家是這樣的。記得還在老家的時(shí)候媽媽...
    研究說明書閱讀 210評論 0 0
  • 《理想》 你知道生活是什么模樣,所以你愛我。 我是你夢中的藍(lán)天,白云,青草與花香。 你追求情調(diào),你追求我。 你渴望...
    擼來神掌閱讀 227評論 0 0