LoginSignup
1
1

More than 5 years have passed since last update.

UIAlertControllerのcompletionにnilを渡すと起きること

Last updated at Posted at 2017-09-11

UIAlertControllerを使う時にdismissの部分でハマッたのでメモ

概要

アラート表示に使うUIAlertControllerを消去・画面遷移する場合に、completionにnilを渡し直列に画面遷移処理を記述すると、dismissが正常に行われず次の画面に残ってしまい影響が出る時がある。

対応方法

アラート消去完了まで待ってあげてから画面遷移を行う

ポイント

UIAlertController dismissの第二引数はnilを渡すのではなく、completion処理を記述する。

サンプル (不具合版)

AlertDisappear_before.m
- (void)shouldTransition
{
    /* dismissの動作が保証されない記述 */
    /* completionの引数がnil指定
    [_alertController dismissViewControllerAnimated:YES completion:nil]; // 第二引数にnilを渡す場合


    NextViewController *nextViewController = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"NextViewController"];
    [self.navigationController pushViewController:nextViewController animated:YES];
}

- (IBAction)tappedAutoDisappear:(id)sender
{
    /* アラート表示を表示する */
    _alertController = [UIAlertController alertControllerWithTitle:@"Discription" message:@"Disappear an alert after transition." preferredStyle:UIAlertControllerStyleAlert];
    [self.navigationController presentViewController:_alertController  animated:YES completion:nil];

    /* アラートを消去し画面遷移する */
    [self performSelector:@selector(shouldTransition) withObject:self afterDelay:3.0f];
}

サンプル(対応版)

AlertDisappear_after.m
- (void)shouldTransition
{
    [_alertController dismissViewControllerAnimated:YES completion: ^{
        // 第二引数にcompletion処理を渡す場合
        NextViewController *nextViewController = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"NextViewController"];
        [self.navigationController pushViewController:nextViewController animated:YES];
    }];
}

- (IBAction)tappedAutoDisappear:(id)sender
{
    /* アラート表示を表示する */
    _alertController = [UIAlertController alertControllerWithTitle:@"Discription" message:@"Disappear an alert after transition." preferredStyle:UIAlertControllerStyleAlert];
    [self.navigationController presentViewController:_alertController  animated:YES completion:nil];

    /* 3秒後にアラートを消去し画面遷移する */
    [self performSelector:@selector(shouldTransition) withObject:self afterDelay:3.0f];
}

備考

アラート表示途中にアプリをバックグラウンドへ、プッシュ通知から起動したら遷移先でアラートの残骸が出たので対応した。

1
1
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
1
1