0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Objective-C]今更UIAlertViewをUIAlertControllerに置き換えようとしてめんどくさいことにハマったので爪痕を残す

Posted at

リファクタリング中のプロジェクトで以下のようなクラスメソッドがあった。

utility.m
+ (void)alertWithTitle:(NSString *)title
               message:(NSString *)message
           buttonTilte:(NSString *)buttonTitle
{
    [[[UIAlertView alloc] initWithTitle:title
                                message:message
                               delegate:nil
                      cancelButtonTitle:buttonTitle
                      otherButtonTitles:nil] show];
}

おう、今更懐かしのUIAlertViewかよ。ってことで、UIAlertControllerに置き換えようとスニペット的に

Utility.m
+ (void)alertWithTitle:(NSString *)title
               message:(NSString *)message
           buttonTilte:(NSString *)buttonTitle
{
      UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
      UIAlertAction *cancelButtonAction = [UIAlertAction actionWithTitle:buttonTitle style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {}];
      [alertController addAction:cancelButtonAction];
      [self presentViewController:alertController animated:YES completion:nil];
}

と書きかけて、ふと困った。これ、ユーティリティ関数のクラスメソッドなので、selfはUIViewControllerではない。
どこから呼び出されるかわからないので、現在表示してるUIViewControllerを拾わなければいけない。

Utility.m
+ (void)alertWithTitle:(NSString *)title
               message:(NSString *)message
           buttonTilte:(NSString *)buttonTitle
{
      UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
      UIAlertAction *cancelButtonAction = [UIAlertAction actionWithTitle:buttonTitle style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {}];
      [alertController addAction:cancelButtonAction];
      UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;

      while (topController.presentedViewController) {
          topController = topController.presentedViewController;
      }
      [topController presentViewController:alertController animated:YES completion:nil];
}

と、今度は、keyWindowはiOS13以降deprecatedだ! 今はUIScene でマルチウィンドウな対応が求められることがある。
といっても、このアプリはUIApplicationDelegateバリバリ採用のレガシーアプリだから、影響はない。
けど気持ち悪い。

なので、keywindow だけ別で拾おう。

https://stackoverflow.com/questions/57134259/how-to-resolve-keywindow-was-deprecated-in-ios-13-0/57899013
から、コードを拝借

Utility.m
+(UIWindow*)keyWindow
{
    UIWindow        *foundWindow = nil;
    NSArray         *windows = [[UIApplication sharedApplication]windows];
    for (UIWindow   *window in windows) {
        if (window.isKeyWindow) {
            foundWindow = window;
            break;
        }
    }
    return foundWindow;
}

これをUtility.mに追加。

ついでに、表示中のUIViewControllerを拾うコードもこのアプリの中でよく使うので、こいつもクラスメソッド化

結果こうなりました。実際のコードには「メインスレッドから絶対に呼べや」ということで、メインスレッド判定などが入ってます。

Utility.m

+ (void)alertOnMainThreadWithTitle:(NSString *)title
                           message:(NSString *)message
                       buttonTilte:(NSString *)buttonTitle
{
      UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
      UIAlertAction *cancelButtonAction = [UIAlertAction actionWithTitle:buttonTitle style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {}];
      [alertController addAction:cancelButtonAction];
      [[Utility topController] presentViewController:alertController animated:YES completion:nil];
}

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?