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];
}
備考
アラート表示途中にアプリをバックグラウンドへ、プッシュ通知から起動したら遷移先でアラートの残骸が出たので対応した。