1. 程式人生 > 其它 >iOS學習——UIAlertController詳解

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提示器上的按鈕-->顯示

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"];
}

  效果圖如下圖所示: