在開發中,彈出提示框是必不可少的。這兩天項目中統一對已經被iOS API廢棄的UIAlertView和UIActionSheet進行替換,我們知道,UIAlertView和UIActionSheet都已經被iOS的API所廢棄了。在兩者的API中都建議用UIAlertController替代,並通過設置不同的類型風格來選擇是原先的UIAlertView或UIActionSheet的形式。
之前項目中一直用的都是原先的UIAlertView和UIActionSheet風格,所以對UIAlertController的了解很少,這次也借着這次統一項目更新的機會對UIAlertController進行了一番學習和研究。UIAlertController是在iOS8.0中出現的一種統一的提示風格的界面,代替原來的UIAlertView和UIActionSheet兩種類別。iOS中學習一個新知識最簡單便捷的兩種方法,一是看官網API,二是看應用示例代碼。下面,我們也從這兩個方面來學習一下UIAlertController。
一 UIAlertController的學習
UIAlertController的API很簡單,其官網API戳這里。關於UIAlertController的API也非常簡單,所有內容如下圖所示。從圖中我們可以看到UIAlertController的內容主要分為五個部分:創建對象、配置UIAlertController對象的屬性、配置UIAlertController上面的按鈕、配置UIAlertController上面的文本框、常量。下面,我們結合實例對這些方法和常量進行學習。
UIAlertController提示器的使用分為三步,創建UIAlertController提示器對象-->配置UIAlertController提示器上的按鈕-->顯示UIAlertController提示器。
1.1 UIAlertController提示器對象的創建
UIAlertController提示器的創建主要是通過類方法來進行創建的,其中第一個參數是標題,第二個參數是內容信息,第三個參數UIAlertControllerStyle則是選擇所創建的UIAlertController對象的類型是UIAlertView 還是 UIActionSheet。UIAlertControllerStyle是一個枚舉類型,其定義就是在UIAlertController.h文件中。
+ (instancetype)alertControllerWithTitle:(NSString *)title message:(NSString *)message preferredStyle:(UIAlertControllerStyle)preferredStyle;
typedef NS_ENUM(NSInteger, UIAlertControllerStyle) { UIAlertControllerStyleActionSheet = 0, UIAlertControllerStyleAlert } NS_ENUM_AVAILABLE_IOS(8_0);
創建常用代碼如下:
//UIAlertView風格 UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"My Alert" message:@"This is an alert." preferredStyle:UIAlertControllerStyleAlert]; //UIActionSheet風格 UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"My Alert" message:@"This is an alert." preferredStyle:UIAlertControllerStyleActionSheet];
1.2 UIAlertController提示器的配置
在UIAlertController提示器中,我們常用的配置有兩類,一是根據需要添加按鈕,並味蕾個按鈕添加點擊事件;二是根據需要添加文本框,用於和用戶進行更多的交互。
1.2.1 UIAlertController上添加按鈕
UIAlertController上的每一個按鈕都是一個UIAlertAction,與UIAlertController的類型是UIAlertView 還是 UIActionSheet無關。UIAlertAction的定義也是就在UIAlertController.h文件中,如下。我們需要在UIAlertController提示器添加一個按鈕時,先創建一個UIAlertAction,然后通過UIAlertController的 addAction: 方法將創建的UIAlertAction對象添加就OK了。
NS_CLASS_AVAILABLE_IOS(8_0) @interface UIAlertAction : NSObject <NSCopying> + (instancetype)actionWithTitle:(nullable NSString *)title style:(UIAlertActionStyle)style handler:(void (^ __nullable)(UIAlertAction *action))handler; @property (nullable, nonatomic, readonly) NSString *title; @property (nonatomic, readonly) UIAlertActionStyle style; @property (nonatomic, getter=isEnabled) BOOL enabled; @end
創建UIAlertAction對象直接用UIAlertAction的類方法就可以創建了,其中第一個參數是按鈕的標題;第二個參數UIAlertActionStyle是選擇按鈕的風格類型,有三種選擇:常規、取消和銷毀風格類型;第三個參數是一個Block,定義了按鈕的點擊響應事件。
+ (instancetype)actionWithTitle:(nullable NSString *)title style:(UIAlertActionStyle)style handler:(void (^ __nullable)(UIAlertAction *action))handler;
UIAlertActionStyle是一個枚舉類型,其定義也是在UIAlertController.h文件中。
typedef NS_ENUM(NSInteger, UIAlertActionStyle) { UIAlertActionStyleDefault = 0, //常規類型,默認藍色字體 UIAlertActionStyleCancel, //取消類型,默認藍色字體 UIAlertActionStyleDestructive //銷毀類型,默認紅色字體,表示可能是要刪除信息 } NS_ENUM_AVAILABLE_IOS(8_0);
常規用法示例如下:
//創建對象 UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet]; //添加銷毀按鈕 UIAlertAction* destructiveBtn = [UIAlertAction actionWithTitle:@"銷毀按鈕" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * action) { NSLog(@"UIAlertActionStyleDestructive"); }]; [alert addAction: destructiveBtn]; //添加默認按鈕 UIAlertAction* defaultBtn = [UIAlertAction actionWithTitle:@"常規按鈕" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) { NSLog(@"UIAlertActionStyleDefault"); }]; [alert addAction:albumBtn]; //添加取消按鈕 UIAlertAction* cancelBtn = [UIAlertAction actionWithTitle:@"取消按鈕" style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) { NSLog(@"UIAlertActionStyleCancel"); }]; [alert addAction:cancelBtn];
1.2.2 UIAlertController上添加文本框
上面我們講到了如何在UIAlertController提示器上添加按鈕,但是有時候,我們需要在提示器上添加一個或多個文本框讓用戶填寫一些信息,在UIAlertController中也提供了一個方法直接可以在提示器上添加文本框。只有一個參數,就是一個Block,用於我們隊該文本框進行配置,比喻說其字體大小,行數限制等等,都可以在該Block中進行設置。
- (void)addTextFieldWithConfigurationHandler:(void (^)(UITextField *textField))configurationHandler;
常見用法示例如下:
[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { NSLog(@"添加一個textField就會調用 這個block"); }];
但是,值得注意的有兩點:
- 文本框的添加只能是在UIAlertController的風格類型為UIAlertView時才有
- 文本框的添加多個
我們可以看到,在配置文本框這里還有一個參數是textFields,這各參數是一個只讀數組類型,用於獲取UIAlertController提示器上所有的文本框對象,這個經常在我們點擊按鈕時用這個來獲取到每一個文本框,並取得用戶填寫的信息。
@property(nonatomic, readonly) NSArray<UITextField *> *textFields;
常見用法如下:
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"title" message:@"message" preferredStyle:UIAlertControllerStyleAlert]; //添加文本框 [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { //設置鍵盤輸入為數字鍵盤 textField.keyboardType = UIKeyboardTypeNumberPad; textField.placeholder = @"請填寫"; }]; UIAlertAction *cancelBtn = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { //取消 }]; [alert addAction: cancelBtn]; //添加確定按鈕 UIAlertAction *confirmBtn = [UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { //文本框結束編輯,收起鍵盤 [[alertVC.textFields firstObject] endEditing:YES]; NSLog(@"%@", [alert.textFields firstObject].text); //獲取文本框填寫的內容 NSString *meetingId = [alertVC.textFields firstObject].text.trim; if(meetingId.length > 12){ [weakSelf showHUDWithText:@"會議號過長"]; }else{ [weakSelf enterVideoMeeting:meetingId]; } }]; [alert addAction: confirmBtn];
1.3 UIAlertController提示器的顯示
UIAlertController提示器的顯示則很簡單,從提示器的類名UIAlertController可以看出,提示器是一個viewController,因此,要顯示提示器,我們一般是是當前viewController的 presentViewController: animated: completion: 方法進行推出,我們創建的提示器。
[self presentViewController:alert animated:YES completion:nil];
1.4 UIAlertController提示器的使用
常規使用示例:
//創建對象 UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"顯示的標題" message:@"標題的提示信息" preferredStyle:UIAlertControllerStyleAlert]; //添加取消類型按鈕 [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { NSLog(@"點擊取消"); }]]; //添加常規類型按鈕 [alertController addAction:[UIAlertAction actionWithTitle:@"確定" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { NSLog(@"點擊確認"); }]]; //添加銷毀類型按鈕 [alertController addAction:[UIAlertAction actionWithTitle:@"警告" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) { NSLog(@"點擊警告"); }]]; //添加文本框 [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { NSLog(@"添加一個textField就會調用 這個block"); }]; //顯示 [self presentViewController:alertController animated:YES completion:nil];
運行的效果圖如下圖所示,左邊是UIAlertView類型的效果圖,右邊是UIActionSheet類型的效果圖。
二 UIAlertController中自定義
在一般情況下,我們只要彈出系統自帶的彈出框就可以。but,在某些情況下,萬惡的UI會要求你修改顯示文字的大小、顏色,雖然系統自帶有一種紅色字體的UIAlertAction,但是這種Action並不能放在Cancel位置,所以,更多時候,需要我們自己修改文字字體和顏色。可是在公開的API接口中好像並沒有對應的方法,那么我們應該怎么做呢?主要的方法有兩種:
- 利用第三方控件
- 利用KVC方法進行自定義修改
2.1 利用第三方控件進行UIAlertController屬性的自定義
現在Github上有着眾多的Alert控件(如SCLAlertView等),相信有很多都可以滿足大家的需求,只要使用Cocoapods添加添加第三方庫就可以了。在這里我們就不詳細進行介紹了。
2.2 利用KVC方法進行UIAlertController屬性的自定義
有時候使用第三方控件會帶來很多不必要的代碼量和bug,所以能用系統自帶的UIAlertController解決是最好的辦法,這樣當然也是可以的。蘋果公司並沒有完全的封死對UIAlertController的定制,而是修改為使用KVC的方法進行定制。如果要自定義標題和內容,可以通過NSAttributedString把字體和顏色設置好,然后在通過KVC的方法進行設置,就可以了。
- (void) test{ UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:@"提示內容" preferredStyle:UIAlertControllerStyleAlert]; // UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:@"提示內容" preferredStyle:UIAlertControllerStyleActionSheet]; //修改title NSMutableAttributedString *alertControllerStr = [[NSMutableAttributedString alloc] initWithString:@"提示"]; [alertControllerStr addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, 2)]; [alertControllerStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:17] range:NSMakeRange(0, 2)]; [alertController setValue:alertControllerStr forKey:@"attributedTitle"]; //修改message NSMutableAttributedString *alertControllerMessageStr = [[NSMutableAttributedString alloc] initWithString:@"提示內容"]; [alertControllerMessageStr addAttribute:NSForegroundColorAttributeName value:[UIColor greenColor] range:NSMakeRange(0, 4)]; [alertControllerMessageStr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:20] range:NSMakeRange(0, 4)]; [alertController setValue:alertControllerMessageStr forKey:@"attributedMessage"]; //常規按鈕 UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"Default" style:UIAlertActionStyleDefault handler:nil]; //銷毀按鈕 UIAlertAction *destructiveAction = [UIAlertAction actionWithTitle:@"Destructive" style:UIAlertActionStyleDestructive handler:nil]; //取消按鈕 UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:nil]; [alertController addAction:defaultAction]; [alertController addAction:destructiveAction]; [alertController addAction:cancelAction]; [self presentViewController:alertController animated:YES completion:nil]; }
效果如下圖所示:
除了可以修改提示器的標題和內容信息的顏色和字號,我們還可以修改按鈕控件的顏色和字號,具體方法如下:
//修改按鈕 if (cancelAction valueForKey:@"titleTextColor") { [cancelAction setValue:[UIColor redColor] forKey:@"titleTextColor"]; }
效果圖如下圖所示: