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

Present UIAlertView from current modal's delegate

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

重要说明: 需要在模式仍在屏幕上时显示此 UIAlertView。包含 tableView 的模态呈现视图不能在用户 selection 之后关闭,因为用户需要能够 select 来自 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 提供答案。

"When the user selects an item, it triggers and action on the delegate"

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

也测试一下。 (ACTION :UIAlertAction!)in

已解决:

使用了以下扩展,感谢 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)

}

这现在允许以下过程:

  1. ContainerView 作为 ItemTableView
  2. 的委托加载
  3. 用户点击searchButton
  4. ContainerView 模态显示项目列表 ItemTableView
  5. 每次用户在 ItemTableView 中选择一行时,都会在呈现 ItemTableViewContainerView 实例中调用 didSelectItem 函数。 ItemTableView 不会被关闭 - 用户可以继续选择项目。
  6. ContainerView 向服务器提交请求
  7. 根据响应,ContainerView 可能会显示 UIAlertView
  8. alertView 使用上述代码在层次结构中最顶层的任何视图之上正确显示。