代码之家  ›  专栏  ›  技术社区  ›  Léo Natan

在iOS8-iOS11中,通过行动表的代表演示视图控制器

  •  58
  • Léo Natan  · 技术社区  · 10 年前

    所以我注意到在iOS8 beta 3中( 使现代化 :在iPad上的iOS 11.2)中,当尝试从 UIActionSheet ,“无”发生,并向调试控制台输出一条日志消息,说明在转换警报控制器时尝试了演示:

    Warning: Attempt to present <UIViewController: 0x...> on <ViewController: 0x...> which is already presenting <UIAlertController: 0x...>
    
    9 回复  |  直到 7 年前
        1
  •  138
  •   Léo Natan    7 年前

    更新: 截至iOS 9 SDK, UIActionSheet 已弃用,因此不要期望对此问题进行修复。最好开始使用 UIAlertController 如果可能的话。


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

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

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

    dispatch_async(dispatch_get_main_queue(), ^ {
        [self presentViewController:vc animated:YES completion:nil];
    });
    
        2
  •  31
  •   Kjuly    10 年前

    您可以尝试在

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

    而不是

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

    正如@LeoNatan所说, “问题似乎来自苹果改用内部使用UIAlertController来实现警报视图和操作表的功能” 。因此,您必须等待操作表被取消,然后呈现所需的视图控制器。

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

        3
  •  4
  •   Achille    10 年前

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

    [segue destinationViewController]
    

    我注意到,如果segue是“push”类型,那么所有的工作都是正确的,但是如果它是“modal”,就在ipad中,我就遇到了这个错误。

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

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

    enter image description here

        4
  •  2
  •   Kaey    10 年前

    我也有同样的问题。我在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];
    
        5
  •  2
  •   Joan Cardona    7 年前

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

      DispatchQueue.main.async {
                self.present(alertController, animated: true, completion: nil)
            }
    
        6
  •  1
  •   user3473830    10 年前

    发布

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

    在…上

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

    在尝试呈现另一种模态视图之前,我觉得很有用。

        7
  •  1
  •   zurakach    10 年前

    使用

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

    而不是

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

    操作视图显示在当前VC之上,因此这就是导致警告/错误的原因。 调用didDismiss时,操作视图已被关闭,因此根本没有问题:))

        8
  •  0
  •   Stuart    10 年前

    尝试

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        // action sheet presentation
        // or modal view controller presentation
        // or alert view presentation
    }];
    
        9
  •  0
  •   Pankaj purohit    9 年前

    在iOS 8中,苹果在内部使用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。