【问题标题】:Present UIAlertView from current modal's delegate从当前模态的委托中呈现 UIAlertView
【发布时间】: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 )需要留在屏幕上 - 它不能被关闭,因为用户需要能够从表中选择多个项目并将每个项目发回给代表。

标签: swift delegates uialertview modalviewcontroller


【解决方案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)

}

现在允许以下过程:

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-22
      • 2020-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多