从当前模态的委托中呈现 UIAlertView

Posted

技术标签:

【中文标题】从当前模态的委托中呈现 UIAlertView【英文标题】:Present UIAlertView from current modal's delegate 【发布时间】:2015-03-31 16:19:52 【问题描述】:

有问题的问题涉及AddItemView,它由其代表以模态方式呈现并包含一个tableView。当用户从 tableView 中选择一个项目时,它会触发委托上的操作。根据来自服务器的响应,委托可能会在当前模式之上呈现另一个模式视图或 UIAlertView。

重要提示:此 UIAlertView 需要在模式仍在屏幕上时呈现。包含 tableView 的模态呈现视图在用户选择后无法关闭,因为用户需要能够从 table 中选择多个项目,并一个一个将它们发送回委托进行处理。

目前,UIAlerView 没有显示,我怀疑这是因为已经呈现的模式阻止了这种情况。当委托位于模态下方且不关闭该模态时,是否有一种解决方法可以从委托中呈现 UIAlertView?

UIAlertView 当前由委托显示,而委托位于模态下:

var alert = UIAlertController(title: "Error", message: "Error message from server", preferredStyle: UIAlertControllerStyle.Alert)

    alert.addAction(UIAlertAction(title: "actionOne", style: .Default, handler:  action in
    // perform some action

    ))

    alert.addAction(UIAlertAction(title: "actionTwo", style: .Destructive, handler:  action in
    // perform some action

    ))

    self.presentViewController(alert, animated: true, completion: nil)

这是委托呈现 UIAlertView 时返回的错误:

Warning: Attempt to present <UIAlertController: 0x156da6300> on <productionLINK_Scanner.ContainerContents: 0x156e65b20> whose view is not in the window hierarchy!

如果可能,请使用 Swift 提供答案。

【问题讨论】:

您尝试在控制器生命周期中的哪个位置显示警报控制器?将控制器放在另一个控制器之上是没有问题的。此外,您不需要在处理程序中关闭警报控制器,它会自动关闭。 @LeoNatan 当用户在呈现的模式的 tableView 中选择一行时,UIAlertView 会从委托中呈现。需要注意的是,模态呈现的 tableView (它实际上是嵌入在 UIView 中的 tableView )需要留在屏幕上 - 它不能被关闭,因为用户需要能够从表中选择多个项目并将每个项目发回给代表。 【参考方案1】:

已解决

使用以下扩展,感谢 GitHub 上的yonat:

extension UIApplication 

    class func topViewController(base: UIViewController? = UIApplication.sharedApplication().keyWindow?.rootViewController) -> UIViewController? 
        if let nav = base as? UINavigationController 
            return topViewController(base: nav.visibleViewController)
        
        if let tab = base as? UITabBarController 
            if let selected = tab.selectedViewController 
                return topViewController(base: selected)
            
        
        if let presented = base?.presentedViewController 
            return topViewController(base: presented)
        
        return base
    

在有问题的委托中,它是这样实现的:

var alert = UIAlertController(title: "Alert Title", message: "Message Body", preferredStyle: UIAlertControllerStyle.Alert)

alert.addAction(UIAlertAction(title: "OK", style: .Default, handler:  action in

))

if let topController = UIApplication.topViewController(base: self) 
    topController.presentViewController(alert, animated: true, completion: nil)

 else 
    // If all else fails, attempt to present the alert from this controller.
    self.presentViewController(alert, animated: true, completion: nil)


现在允许以下过程:

    ContainerView 被加载为 ItemTableView 的代表 用户点击searchButton ContainerView 模态显示项目列表 ItemTableView 每次用户选择ItemTableView 中的一行时,didSelectItem 函数就会在提供ItemTableViewContainerView 实例中调用。 ItemTableView 不会被关闭 - 用户可以继续选择项目。 ContainerView 向服务器提交请求 根据响应,ContainerView 可能会显示UIAlertViewalertView 使用上述代码正确显示在层次结构中最顶层的任何视图之上。

【讨论】:

【参考方案2】:

“当用户选择一个项目时,它会触发并作用于委托”

在委托方法的开始处设置一个断点,该方法是通过选择一个项目来触发的。检查是否正在调用该委托方法?

并对此进行测试。 (ACTION :UIAlertAction!)in

【讨论】:

以上是关于从当前模态的委托中呈现 UIAlertView的主要内容,如果未能解决你的问题,请参考以下文章

从应用程序委托不平衡调用开始/结束外观呈现模态视图

来自应用委托的 presentModalViewController

从 SubView 呈现模态 ViewController

如何在应用程序委托iOS10 Objective C中的applicationWillEnterForeground方法中以模态方式呈现UIViewController

使用模态呈现的 NavigationController(iOS 5 - Storyboard)时,委托不起作用

如何在没有委托的情况下以模态方式呈现 ViewController,然后在 ViewController 被解除后运行回调函数/块?