[iOS 8] UIAlertView と UIActionSheet が deprecated になった

UIAlertController

iOS8 からは UIAlertView, UIActionSheet が deprecated となり、替わりに UIAlertController という新規のクラスを使うことが推奨されました。

これらの違いを一言で説明すると、

ボタンがタップされた時の処理を

  • UIAlertView, UIActionSheet はデリゲートメソッドで実装する
  • UIAlertController はブロックで実装する

となっています。

サンプルコード(アラート)

実行時の画面

AlertView

従来のコードで記述

アラート表示処理

[[[UIAlertView alloc] initWithTitle:@"Title"
                            message:@"Message"
                           delegate:self
                  cancelButtonTitle:@"Cancel"
                  otherButtonTitles:@"OK", nil] show];

ボタンタップ時の処理

// UIAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (buttonIndex == alertView.cancelButtonIndex) {
        NSLog(@"Cancel button tapped.");
    } else {
        NSLog(@"OK button tapped.");
    }
}

UIAlertController で記述

// コントローラを生成
UIAlertController * ac =
    [UIAlertController alertControllerWithTitle:@"Title"
                                        message:@"Message"
                                 preferredStyle:UIAlertControllerStyleAlert];

// Cancel用のアクションを生成
UIAlertAction * cancelAction =
    [UIAlertAction actionWithTitle:@"Cancel"
                             style:UIAlertActionStyleCancel
                           handler:^(UIAlertAction * action) {
                               // ボタンタップ時の処理
                               NSLog(@"Cancel button tapped.");
                           }];

// OK用のアクションを生成
UIAlertAction * okAction =
    [UIAlertAction actionWithTitle:@"OK"
                             style:UIAlertActionStyleDefault
                           handler:^(UIAlertAction * action) {
                               // ボタンタップ時の処理
                               NSLog(@"OK button tapped.");
                           }];

// コントローラにアクションを追加
[ac addAction:cancelAction];
[ac addAction:okAction];

// アラート表示処理
[self presentViewController:ac animated:YES completion:nil];

preferredStyle に UIAlertControllerStyleAlert を指定するとアラートが表示されます。

サンプルコード(アクションシート)

実行時の画面

ActionSheet

従来のコードで記述

アクションシート表示処理

[[[UIActionSheet alloc] initWithTitle:@"Title"
                             delegate:self
                    cancelButtonTitle:@"Cancel"
               destructiveButtonTitle:@"Destructive"
                    otherButtonTitles:@"OK", nil] showInView:self.view];

ボタンタップ時の処理

// UIActionSheetDelegate
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    if (buttonIndex == actionSheet.cancelButtonIndex) {
        NSLog(@"Cancel button tapped.");
    } else if (buttonIndex == actionSheet.destructiveButtonIndex) {
        NSLog(@"Destructive button tapped.");
    } else {
        NSLog(@"OK button tapped.");
    }
}

UIAlertController で記述

// コントローラを生成
UIAlertController * ac =
    [UIAlertController alertControllerWithTitle:@"Title"
                                        message:@"Message"
                                 preferredStyle:UIAlertControllerStyleActionSheet];

// Cancel用のアクションを生成
UIAlertAction * cancelAction =
    [UIAlertAction actionWithTitle:@"Cancel"
                             style:UIAlertActionStyleCancel
                           handler:^(UIAlertAction * action) {
                               // ボタンタップ時の処理
                               NSLog(@"Cancel button tapped.");
                           }];

// Destructive用のアクションを生成
UIAlertAction * destructiveAction =
    [UIAlertAction actionWithTitle:@"Destructive"
                             style:UIAlertActionStyleDestructive
                           handler:^(UIAlertAction * action) {
                               // ボタンタップ時の処理
                               NSLog(@"Destructive button tapped.");
                           }];

// OK用のアクションを生成
UIAlertAction * okAction =
    [UIAlertAction actionWithTitle:@"OK"
                             style:UIAlertActionStyleDefault
                           handler:^(UIAlertAction * action) {
                               // ボタンタップ時の処理
                               NSLog(@"OK button tapped.");
                           }];

// コントローラにアクションを追加
[ac addAction:cancelAction];
[ac addAction:destructiveAction];
[ac addAction:okAction];

// アクションシート表示処理
[self presentViewController:ac animated:YES completion:nil];

preferredStyle に UIAlertControllerStyleActionSheet を指定するとアクションシートが表示されます。

感想

表示処理とボタンタップ時の処理がひとまとまりになったことと、if 文が無くなったことによって可読性が上がった気がしました。

いいと思います。

ただ、ボタンをタップしてから「ボタンタップ時の処理」が実行されるまでの時間が、UIAlertController で記述したほうが従来のコードに比べて長いように感じました。
これはそのうち短くなることを期待します。

なお動作確認したところ、UIAlertController のブロック処理部分はメインスレッドで実行されていたので、ブロック内で UI 操作を行っても大丈夫でしょう。

おまけ

Swift で UIAlertController

var ac = UIAlertController(title: "Title", message: "Message", preferredStyle: .Alert)

let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (action) -> Void in
    println("Cancel button tapped.")
}

let okAction = UIAlertAction(title: "OK", style: .Default) { (action) -> Void in
    println("OK button tapped.")
}

ac.addAction(cancelAction)
ac.addAction(okAction)

presentViewController(ac, animated: true, completion: nil)

関連記事