【Xcode】UIAlertController呼び出しを簡略化する
UIAlertControllerを使って一般的なOK、Cancelボタン付きのアラートを表示するには
次のようにコードを書きます。
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"title" message:@"message" preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){ NSLog(@"Ok is pressed."); }]; [alert addAction:okAction]; UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action){ NSLog(@"Cancel is pressed."); }]; [alert addAction:cancelAction]; [self presentViewController:alert animated:YES completion:nil];
…長い。
OK、Cancelなどのお決まりの文字列を定数として定義する手間も加えると
ただ短いメッセージを出すだけなのに結構面倒くさいです。
そこで、UIAlertController呼び出しを簡略化するUtilAlertクラスを作りました。
UtilAlert.h
#import <UIKit/UIKit.h> @interface UtilAlert : NSObject // OKボタンを持つAlertを表示 + (void)showAlertOkWithTitle:(NSString *)title message:(NSString *)message okHandler:(void (^)(UIAlertAction *action))okHandler; // OK、Cancelボタンを持つAlertを表示 + (void)showAlertOkCancelWithTitle:(NSString *)title message:(NSString *)message okHandler:(void (^)(UIAlertAction *action))okHandler cancelHandler:(void (^)(UIAlertAction *action))cancelHandler; @end
UtilAlert.m
#import "UtilAlert.h" static NSString *const AlertButtonOk = @"OK"; static NSString *const AlertButtonCancel = @"Cancel"; @implementation UtilAlert #pragma mark - Private Methods /** * rootViewControllerを取得 * * @return rootViewControllerインスタンス */ + (UIViewController *)rootViewController { UIViewController *root = [UIApplication sharedApplication].keyWindow.rootViewController; while (root.presentedViewController != nil && !root.presentedViewController.isBeingDismissed) { root = root.presentedViewController; } return root; } #pragma mark - Public Methods /** * OKボタンを持つAlertを表示 * * @param title タイトル * @param message 本文 * @param okHandler OKボタンタップ時の処理 * */ + (void)showAlertOkWithTitle:(NSString *)title message:(NSString *)message okHandler:(void (^)(UIAlertAction *action))okHandler { UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *okAction = [UIAlertAction actionWithTitle:AlertButtonOk style:UIAlertActionStyleDefault handler:okHandler]; [alert addAction:okAction]; [[UtilAlert rootViewController] presentViewController:alert animated:YES completion:nil]; } /** * OK、Cancelボタンを持つAlertを表示 * * @param title タイトル * @param message 本文 * @param okHandler OKボタンタップ時の処理 * @param cancelHandler Cancelボタンタップ時の処理 * */ + (void)showAlertOkCancelWithTitle:(NSString *)title message:(NSString *)message okHandler:(void (^)(UIAlertAction *action))okHandler cancelHandler:(void (^)(UIAlertAction *action))cancelHandler { UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *okAction = [UIAlertAction actionWithTitle:AlertButtonOk style:UIAlertActionStyleDefault handler:okHandler]; [alert addAction:okAction]; UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:AlertButtonCancel style:UIAlertActionStyleCancel handler:cancelHandler]; [alert addAction:cancelAction]; [[UtilAlert rootViewController] presentViewController:alert animated:YES completion:nil]; }
このUtilAlertを使って冒頭の処理を書き換えると以下のようになります。
[UtilAlert showAlertOkCancelWithTitle:@"title" message:@"message" okHandler:^(UIAlertAction *action){ NSLog(@"Ok is pressed."); } cancelHandler:^(UIAlertAction *action){ NSLog(@"Cancel is pressed."); }];
コード量が半分に減りました。
解説
presentViewController: はUIViewController派生クラスからしか呼ぶことができません。
なので、[UtilAlert rootViewController] メソッドを作り、ルートとなるViewControllerを取得しています。
これにより、例えば通信クラスなど画面ではない処理からアラートを出すこともできます。