从当前模态的委托中呈现 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
函数就会在提供ItemTableView
的ContainerView
实例中调用。 ItemTableView
不会被关闭 - 用户可以继续选择项目。
ContainerView
向服务器提交请求
根据响应,ContainerView
可能会显示UIAlertView
。
alertView
使用上述代码正确显示在层次结构中最顶层的任何视图之上。
【讨论】:
【参考方案2】:“当用户选择一个项目时,它会触发并作用于委托”
在委托方法的开始处设置一个断点,该方法是通过选择一个项目来触发的。检查是否正在调用该委托方法?
并对此进行测试。 (ACTION :UIAlertAction!)in
【讨论】:
以上是关于从当前模态的委托中呈现 UIAlertView的主要内容,如果未能解决你的问题,请参考以下文章
来自应用委托的 presentModalViewController
如何在应用程序委托iOS10 Objective C中的applicationWillEnterForeground方法中以模态方式呈现UIViewController
使用模态呈现的 NavigationController(iOS 5 - Storyboard)时,委托不起作用
如何在没有委托的情况下以模态方式呈现 ViewController,然后在 ViewController 被解除后运行回调函数/块?