iOS學習——UIAlertController詳解
在開發中,彈出提示框是必不可少的。這兩天專案中統一對已經被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提示器上的按鈕-->顯示
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"];
}
效果圖如下圖所示: