58

所以我注意到,在 iPad 上的 iOS8 beta 3(更新:iOS 11.2 中仍然发生)中,当尝试从 a 的委托方法中呈现视图控制器时UIActionSheet,“什么都没有”发生并且日志消息输出到调试控制台,说明在转换警报控制器时尝试了演示:

Warning: Attempt to present <UIViewController: 0x...> on <ViewController: 0x...> which is already presenting <UIAlertController: 0x...>
4

9 回答 9

138

更新:从 iOS 9 SDK 开始,UIActionSheet已弃用,因此不要指望修复此问题。最好尽可能开始使用UIAlertController


问题似乎来自 Apple 转而在UIAlertController内部使用来实现警报视图和操作表的功能。该问题主要出现在 iPad 和操作表上,因为在 iPad 上,操作表在指定视图中显示为弹出框,Apple 所做的是遍历响应者链,直到找到视图控制器并presentViewController:animated:completion:使用内部UIAlertController. 这个问题在 iPhone 和警报视图上不太明显,因为苹果实际上创建了一个单独的窗口,一个空的视图控制器并在其UIAlertController上呈现内部,所以它似乎不会干扰其他呈现。

我已经打开了这个问题的错误报告:rdar://17742017。请复制它并让 Apple 知道这是一个问题。

作为一种解决方法,我建议使用以下方法将演示延迟到下一个运行循环:

dispatch_async(dispatch_get_main_queue(), ^ {
    [self presentViewController:vc animated:YES completion:nil];
});
于 2014-07-20T20:52:15.580 回答
31

您可以尝试在

- (void)      actionSheet:(UIActionSheet *)actionSheet
didDismissWithButtonIndex:(NSInteger)buttonIndex {}

代替

- (void) actionSheet:(UIActionSheet *)actionSheet
clickedButtonAtIndex:(NSInteger)buttonIndex {}

正如@LeoNatan 所说,“问题似乎来自Apple 切换到在内部使用UIAlertController 来实现警报视图和操作表的功能”。所以你必须等待动作表被解雇,然后呈现你想要的视图控制器。

@LeoNatan 的解决方案只是在主线程中阻止 UI,因此它还将确保在关闭操作表后显示视图控制器。

于 2014-09-30T02:06:58.857 回答
4

不幸的是,这段代码对我不起作用,我想是因为我的问题不是直接调用 presentController 方法,而是在 prepareForSegue 方法中使用

[segue destinationViewController]

我注意到如果 segue 是“push”类型的,一切正常,但如果它是“modal”,就在 ipad 中,我得到了那个错误。

然后我在 segue 面板的情节提要中找到了一些新选项,我解决了为演示选项选择“当前上下文”的问题

我希望这对其他人有帮助...这是有关该选项的屏幕截图

在此处输入图像描述

于 2014-09-24T09:39:47.487 回答
2

我有同样的问题。我在我的 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];
于 2015-02-09T09:37:34.023 回答
2

我使用以下代码在 Swift 3 中修复了它

  DispatchQueue.main.async {
            self.present(alertController, animated: true, completion: nil)
        }
于 2017-04-21T14:37:00.480 回答
1

发行

[self.navigationController dismissViewControllerAnimated:YES completion:nil];

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex 

在尝试呈现另一个模式视图之前对我有用。

于 2014-10-15T03:33:53.090 回答
1

采用

- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex

代替

- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex

动作视图显示在当前 VC 上方,这就是导致警告/错误的原因。当 didDismiss 被调用时,动作视图已经被关闭,所以完全没有问题 :))

于 2015-02-04T13:27:51.427 回答
0

尝试

[[NSOperationQueue mainQueue] addOperationWithBlock:^{
    // action sheet presentation
    // or modal view controller presentation
    // or alert view presentation
}];
于 2015-02-11T13:22:05.660 回答
0

在 iOS 8 中,Apple 在内部使用 UIAlertController 来实现警报视图和操作表的功能。因此,当您想在委托方法中显示 UIActionSheet 或 UIAlertView 后以模态方式显示 UIViewController 时,例如

(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。

于 2015-02-20T14:41:20.643 回答