警告:尝试在已经呈现的 MainTableViewController 上呈现 ModalTableViewController (null)

Posted

技术标签:

【中文标题】警告:尝试在已经呈现的 MainTableViewController 上呈现 ModalTableViewController (null)【英文标题】:Warning: Attempt to present ModalTableViewController on MainTableViewController which is already presenting (null) 【发布时间】:2014-10-02 12:04:43 【问题描述】:

我的弹出框有问题。如果我点击一个单元格,我将加载一个弹出框以选择更多详细信息。一切正常,但是当我再次按下我的手机时,我每次都会收到以下消息:

警告:尝试在 MainTableViewController... 上展示 ModalTableViewController... 已经展示(null)

如果我点击另一个单元格,我将不会收到此警告。仅当再次点击同一行时。

我尝试了很多东西,但我无法解决这个问题。我像这样加载我的弹出窗口:

var popover: UIPopoverController!
var popoverContent: ModalTableViewController!

在我的手机上点击:

popoverContent = self.storyboard.instantiateViewControllerWithIdentifier("ModalTableViewController") as ModalTableViewController

popoverContent.selectedQuestionID = indexPath!.row               
popover = UIPopoverController(contentViewController: popoverContent)
popover.delegate = self

popover.presentPopoverFromRect(currentCell.LabelCellTitle.frame, inView: currentCell.LabelCellTitle.superview, permittedArrowDirections: UIPopoverArrowDirection.Left, animated: true)

然后解雇

func popoverControllerDidDismissPopover(popoverController: UIPopoverController!) 

    popover.dismissPopoverAnimated(false) // just to check

    self.popover = nil
    self.popoverContent = nil


有什么想法吗?

编辑:

如果我检查:

if(self.popoverContent == nil) 

在打开它之前,当我再次点击同一个单元格时,我会发现它不是零。

再次编辑:

如果我用稍微不同的设置创建它,我也会遇到同样的问题:

自定义 1x1px 按钮。将弹出框与 segue 连接。在单元格上点击移动按钮到单元格并打开弹出框。

所以没有打开弹出框的代码,只有故事板编辑器。

如果我再次点击相同的弹出框,我会收到相同的错误消息(有时)。

【问题讨论】:

您可能只想选择objective-c 和swift 标签中的一个,以免让像我这样的人感到困惑。 :) 我认为拥有丰富 Obj-C 经验的人也应该知道答案 ;) 只需将演示文稿包装在里面:NSOperationQueue.mainQueue().addOperationWithBlock //Your presentation call 就足以完成这项工作。 【参考方案1】:

我遇到了这个问题,因为我试图从内部执行 segue/present:

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

我改成:

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

它修复了它!

【讨论】:

这就是我的情况。一个愚蠢问题的简单解决方案。 这也解决了我的问题。 此解决方案是否会导致任何其他需要处理的问题?刚刚问了 这为我解决了这个问题。但是如果我们使用 clickedButtonAtIndex 或 didDismissWithButtonIndex 有什么区别呢?谁能解释一下。 @RajTandel 有一段时间了,但我认为可能不会在主线程上调用 clickedButtonAtIndex (为什么大多数其他答案建议调度回主队列)。【参考方案2】:

我还没有使用 swift,但是对于 Objective-C,我最终将 presentViewController 调用包装在 performSelector 调用中。

-(void) present

    [self performSelector: @selector(ShowModalTableViewController) withObject: nil afterDelay: 0];


-(void) ShowModalTableViewController

    [self presentViewController: ctrlModalTableViewController animated: true completion: nil];

【讨论】:

不知道为什么这被否决了。这实际上为我解决了这个问题。 我有一个应用程序在 ios7 中运行良好,但在 IOS8 中出现了这个问题。这个提示修复了它。 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^ /* 把要执行的代码放在这里 */ );还为我在 iOS 8 上修复了它,以防您不想创建一个新方法只是为了调用相同的代码。 如果您是从 ActionSheet 按钮中进行演示,请单击 - 尝试 @Steve 使用 didDismissWithButtonIndex 的答案 以上确实解决了 iOS 8 中的问题/错误。但这是一种破解方法。史蒂夫切换到使用 didDismissWithButtonIndex: 的答案是更好的解决方案。看看史蒂夫的回答。它的工作量更少,也更不脆弱。【参考方案3】:

这也可以:

dispatch_async(dispatch_get_main_queue(), ^ 
        [self presentViewController:vc animated:YES completion:nil];
);

【讨论】:

这为我解决了类似的问题。但是我不明白为什么会这样。为什么我需要这样做?有任何链接可以提供更多背景信息吗? 它在不同的线程上运行 presentViewController,因此不再有冲突。至于为什么——因为 Apple 一定改变了他们在幕后处理这些事情的方式。 不同的线程?我没有跟随。 dispatch_get_main_queue() 应该给你主 UI 线程的权利,这就是我所说的。 我认为您提出的解决方案可能有效,但必须将其视为令人讨厌的 hack。它没有解决在消除前一个问题之前弹出的问题的根源。确保你已经解雇了旧的,然后展示了新的。它的工作原理是为主运行循环的下一次运行添加更改 非常感谢,它拯救了我的一天,我发现这个问题发生在我的 iPad 上,但 iPhone 完全没有问题【参考方案4】:

在弹出框上展示任何东西似乎都是如此。之前所有响应都起作用的原因很可能是因为正在采取的任何操作都发生在弹出框(或活动表或类似内容)被解除之前。

如果可以,请先尝试关闭弹出框,然后再展示您的模式。

【讨论】:

【参考方案5】:

这实际上是 iPad 上的 iOS 8 问题,在低于 8 的 iOS 中不会发生。您可以在那里设置条件:

if ([controller respondsToSelector:@selector(popoverPresentationController)])

    // iOS8
    controller.popoverPresentationController.sourceView = self.view; // or any of your UIiew

但请考虑以下史蒂夫的观点 (https://***.com/a/26380194/362310) 与此代码更改。

【讨论】:

【参考方案6】:

只需将此代码 sn-p 添加到主 uiviewcontroller 的 ViewDidLoad() 中即可

 definesPresentationContext = true

【讨论】:

【参考方案7】:

如果 UIActionSheet 在新的视图控制器演示调用时出现,就会发生这种情况,例如 这段代码对我有用

    [[NSOperationQueue mainQueue] addOperationWithBlock:^
        [controller presentViewController:modalViewController animated:YES completion:NULL];
    ];

【讨论】:

【参考方案8】:

对我来说,这发生在我有两个 UIBarButton 项目作为 NavigationItem 的一部分并且两者都有触发的 segue 以将视图打开为弹出框 - 使用它们自己的控制器。点击另一个 BarButtonItem 时,一个弹出框不会自动关闭。然而,当我点击弹出框之外的其他地方时,它会消失。 我最终覆盖了 UINavigationController 并添加了 presentViewController:animated:completion 的扩展版本

/*
 * Workaround for apparent bug in iPad that popover does not automatically dismiss if another bar button item is pressed
 */

- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion 

    /*
     * Make sure this runs in the main queue
     */
    dispatch_async(dispatch_get_main_queue(), ^ 
        if (
            [self.presentedViewController isKindOfClass:[ViewController1 class]]
            || [self.presentedViewController isKindOfClass:[ViewController2 class]]
            || [self.presentedViewController isKindOfClass:[ViewController3 class]]
            || [self.presentedViewController isKindOfClass:[ViewController4 class]]
            ) 
            [self dismissViewControllerAnimated:YES completion:^
                [super presentViewController:viewControllerToPresent animated:flag completion:completion];
            ];
        

        else 
            [super presentViewController:viewControllerToPresent animated:flag completion:completion];
        
    );

我认为dispatch_async(dispatch_get_main_queue(), ^ ) 并不是真正需要的,我只是添加它以防万一。

【讨论】:

【参考方案9】:

在我的例子中,我不小心将我的按钮同时链接到 IBActionStoryboard Segue 类型为 Present As Popover。我解决这个问题的方法是将按钮的Touch Up Inside 事件链接删除到IBAction,并且只使用了Storyboard Segue

【讨论】:

以上是关于警告:尝试在已经呈现的 MainTableViewController 上呈现 ModalTableViewController (null)的主要内容,如果未能解决你的问题,请参考以下文章

警告:尝试在其视图不在窗口层次结构中的 * 上呈现 * - swift

警告:尝试呈现不在窗口层次结构中的视图!在 UISearchController

警告:尝试在已呈现 <RCTModalHostViewController> 的 <RNNsideMenuController> 上呈现 <UINavigationCon

警告 - 尝试在 Swift 中呈现 UIAlertController null

警告:尝试在视图不在窗口层次结构中的 **.ViewController 上呈现 ZMNavigationController

警告:尝试在已呈现的 <...> 上呈现 <UIAlertController: 0x7facd3946920> (null)