だから私はiOS8ベータ3(pdate:iOS 11.2でもまだ発生する)で、UIActionSheet
のデリゲートメソッド内からView Controllerを表示しようとしたときに気づいた」が発生し、ログメッセージがデバッグコンソールに出力され、アラートコントローラーの移行中にプレゼンテーションが試行されたことを示します。
Warning: Attempt to present <UIViewController: 0x...> on <ViewController: 0x...> which is already presenting <UIAlertController: 0x...>
更新: iOS 9 SDK以降、UIActionSheet
は非推奨になったため、この問題に関する修正を期待しないでください。可能であれば、UIAlertController
の使用を開始することをお勧めします。
この問題は、UIAlertController
を内部で使用してアラートビューとアクションシートの機能を実装することにAppleが切り替えたために発生したようです。 iPadでは、指定されたビュー内でアクションシートがポップオーバーとして表示されるため、問題は主にiPadとアクションシートで見られます。また、ビューを見つけるまでレスポンダーチェーンを移動するのはAppleコントローラーと呼び出しpresentViewController:animated:completion:
と内部UIAlertController
。この問題はiPhoneとアラートビューではそれほど明白ではありません。Appleは実際に別のウィンドウ、空のView Controllerを作成し、その上に内部UIAlertController
を提示するため、他のプレゼンテーションに干渉しないようです。
この問題のバグレポートを開きました:rdar:// 17742017。複製して、Appleこれが問題であることを知らせてください。
回避策として、次の方法を使用して、次のランループまでプレゼンテーションを遅らせることをお勧めします。
dispatch_async(dispatch_get_main_queue(), ^ {
[self presentViewController:vc animated:YES completion:nil];
});
あなたはあなたの仕事をすることができます(View Controllerを提示する)
- (void) actionSheet:(UIActionSheet *)actionSheet
didDismissWithButtonIndex:(NSInteger)buttonIndex {}
の代わりに
- (void) actionSheet:(UIActionSheet *)actionSheet
clickedButtonAtIndex:(NSInteger)buttonIndex {}
@LeoNatanが言ったように、「問題は、アラートビューとアクションシートの機能を実装するために、UIAlertControllerを内部で使用するAppleのスイッチに起因するようです」。そのため、アクションシートが閉じられるのを待ってから、必要なView Controllerを提示する必要があります。
@LeoNatanのソリューションは、メインスレッドでUIをブロックするだけなので、アクションシートが閉じられた後にView Controllerが表示されることも確認します。
残念ながら、このコードは私には機能しません。私の問題はpresentControllerメソッドを直接呼び出すのではなく、prepareForSegueメソッドで呼び出していたためだと思います
[segue destinationViewController]
セグエが「プッシュ」である場合はすべて正常に動作しますが、「モーダル」である場合は、iPadのみで、そのエラーが発生します。
その後、私はセグエパネルのストーリーボードでいくつかの新しいオプションを見つけ、プレゼンテーションオプションに「現在のコンテキスト」を選択する問題を解決しました
これが他の人に役立つことを願っています...ここにオプションに関するスクリーンショットがあります
これと同じ問題がありました。 appdelegateでアラートとアクションシート用に別のウィンドウを作成し、アラートを表示しました。それは私のために働いた!
self.alertWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.alertWindow.backgroundColor = [UIColor clearColor];
UIViewController *dummy = [[UIViewController alloc] init];
[self.alertWindow setRootViewController:dummy];
次のように表示できます:
[[myAppDelegate appDelegate].alertWindow makeKeyAndVisible];
[[myAppDelegate appDelegate].alertWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
次のコードでSwift 3で修正しました
DispatchQueue.main.async {
self.present(alertController, animated: true, completion: nil)
}
つかいます
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
の代わりに
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
アクションビューは現在のVCの上に表示されるため、警告/エラーの原因となります。didDismissが呼び出されたとき、アクションビューは既に閉じられているため、問題はありません:))
発行
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
オン
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
別のモーダルビューを表示しようとする前に私のために働いた。
IOS 8では、AppleはUIAlertControllerを内部的に使用してアラートビューとアクションシートの機能を実装します。したがって、デリゲートメソッドでUIActionSheetまたはUIAlertView
(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
そして
(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
次のように、最初にUIAlertControllerを閉じる必要があります。
if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0"))
{
UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
[vc dismissViewControllerAnimated:NO completion:^{
}];
}
IOS 8でモーダルUIViewControllerを表示できるようになりました。
試して
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// action sheet presentation
// or modal view controller presentation
// or alert view presentation
}];