在iOS8 – iOS10中从操作表代表以模态方式呈现视图控制器
所以我注意到,在iPad上,当试图从UIActionSheet
的委托方法中呈现视图控制器时,在iOS8 beta 3( 更新 :仍然发生在iOS 10中)上,“nothing”发生并且日志消息被输出到debugging控制台,表示在转换警报控制器的过程中尝试了演示文稿:
Warning: Attempt to present <UIViewController: 0x...> on <ViewController: 0x...> which is already presenting <UIAlertController: 0x...>
更新:在iOS 9 SDK中, UIActionSheet
已被弃用,所以不要指望修复这个问题。 如果可能,最好开始使用UIAlertController
。
这个问题似乎来自苹果切换到内部使用UIAlertController
来实现警报视图和操作表的function。 这个问题主要出现在iPad和动作表上,因为在iPad上,动作表是作为指定视图内的popup窗口显示的,而苹果所做的就是presentViewController:animated:completion:
响应者链,直到find视图控制器并调用presentViewController:animated:completion:
与内部UIAlertController
。 这个问题在iPhone和alert视图上不太明显,因为Apple实际上创build了一个单独的窗口,一个空的视图控制器,并在其上面显示了内部UIAlertController
,所以它似乎不会干扰其他演示。
我已经打开这个问题的错误报告: rdar:// 17742017 。 请复制它,让苹果知道这是一个问题。
作为一种解决方法,我推荐使用以下方法来延迟演示,直到下一个runloop:
dispatch_async(dispatch_get_main_queue(), ^ { [self presentViewController:vc animated:YES completion:nil]; });
你可以尝试做你的工作(呈现视图控制器)
- (void) actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {}
代替
- (void) actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {}
正如@LeoNatan所说: “这个问题似乎来自苹果公司内部使用UIAlertController来实现警报视图和操作表的function” 。 所以你必须等待行动表被解散,然后呈现你想要的视图控制器。
@LeoNatan的解决scheme就是在主线程中阻止用户界面,所以它也会确保视图控制器在操作表被解除后呈现。
不幸的是这个代码不适用于我,我想因为我的问题不是直接调用presentController方法,而是在prepareForSegue方法中,所以使用
[segue destinationViewController]
我注意到,如果segue是“推”类的所有工作正常,但如果它是“模态”,只是在iPad中,我得到了这个错误。
然后,我在segue面板的storyboard中find了一些新的选项,并且我select了“Current context”作为Presentation选项
我希望这将有助于别人…这是关于选项的截图
我有同样的问题。 我在我的appdelegate中创build了一个单独的警报和动作表窗口,并在其上显示警报。 它为我工作!
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];
发出一个
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
上
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
然后尝试呈现另一种模式的看法为我工作。
使用
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
代替
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
动作视图是在当前的VC上方呈现的,因此是什么导致警告/错误。 当didDismiss被调用时,动作视图已经被解散,所以没有任何问题:))
我使用下面的代码在Swift 3中修复了它
DispatchQueue.main.async { self.present(alertController, animated: true, completion: nil) }
尝试
[[NSOperationQueue mainQueue] addOperationWithBlock:^{ // action sheet presentation // or modal view controller presentation // or alert view presentation }];
在iOS 8中,Apple内部使用UIAlertController来实现警报视图和操作表的function。 所以,当你想要显示一个UIViewController模态后显示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。