当 ViewController 被呈现的 ViewController 覆盖时触发事件

Posted

技术标签:

【中文标题】当 ViewController 被呈现的 ViewController 覆盖时触发事件【英文标题】:Trigger events when ViewController covered by a presented ViewController 【发布时间】:2016-11-04 12:38:38 【问题描述】:

我想在 ViewController 由于呈现新的 ViewController 而不再可见时处理代码。

我不能使用 ViewWillDisappear 等,因为从技术上讲,控制器从未从堆栈中解散 - 你只是看不到它。

当控制器不再可见(即最顶层)和控制器再次可见时,我可以使用什么进程来运行代码?

编辑: 这里似乎有些混乱 - 不知道为什么。 我有一个视图控制器。 我使用下面的代码来展示另一个控制器

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let navController = storyboard.instantiateViewControllerWithIdentifier("NavController") as! UINavigationController
let thisController = navController.viewControllers[0] as! MyController
self.presentViewController(navController, animated: true, completion: nil)

此控制器不会在前一个控制器上触发 viewWillDisappear,因为前一个视图没有被删除 - 只是隐藏。

当这个视图被隐藏(即不可见)时,我需要处理代码,更重要的是,当它再次可见时处理代码。

【问题讨论】:

在这里详细说明。 请提供更多细节,说明您希望在演示控制器被不同的 VC 覆盖时继续执行什么样的任务。另外,详细说明为什么 viewDidDisappear 不能解决问题 不确定如何详细说明——我展示了一个视图控制器,它涵盖了前一个控制器,当这种情况发生时我需要前一个控制器来处理代码(实际上我可以以某种方式处理)——问题是当原始控制器再次可见时如何处理代码 你能把截图放在这里吗? 啊,您是在用UIModalPresentationOverCurrentContext 介绍新的UIViewController 吗? 【参考方案1】:

当呈现UIViewController 时,如果呈现样式已设置为UIModalPresentationOverCurrentContext,它不会调用viewWillDisappear 和相关方法,因为视图永远不会消失或隐藏。

检查是否是这种情况的一个简单测试是将您正在使用的 NavController 设置为具有清晰的背景颜色。如果您这样做并呈现 NavController,您仍然可以查看 NavController 内容下方的第一个 UIViewController。然后你正在使用UIModalPresentationOverCurrentContext,这就是为什么不调用viewDidDisappear

看看 Serghei Catraniuc (https://***.com/a/30787112/4539192) 引用的答案。

【讨论】:

【参考方案2】:

编辑:这是在 Swift 3 中,如果您使用的是旧版本的 Swift,您可以相应地调整您的方法

如果您无法弄清楚为什么没有调用 viewDidAppearviewDidDisappear,这里有一个解决方法

protocol MyControllerDelegate 
    func myControllerWillDismiss()


class MyController: UIViewController 
    var delegate: MyControllerDelegate?

// your controller logic here

    func dismiss()  // call this method when you want to dismiss your view controller

        // inform delegate on dismiss that you're about to dismiss
        delegate?.myControllerWillDismiss()
        dismiss(animated: true, completion: nil)
    


class PresentingController: UIViewController, MyControllerDelegate  
    func functionInWhichYouPresentMyController() 
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let navController = storyboard.instantiateViewController(withIdentifier: "NavController") as! UINavigationController
        let thisController = navController.viewControllers[0] as! MyController
        thisController.delegate = self // assign self as delegate
        present(navController, animated: true, completion: 
            // place your code that you want executed when it disappears here
        )
    

    func myControllerWillDismiss() 
        // this method will be called now when MyController will dismiss
        // place your code that you want executed when it re-appears here
    

【讨论】:

非常感谢 - 您是否也可以发布您所说的与呈现控制器 viewDidDisappear 一起使用的呈现代码?我在 Swift2 中使用的代码在我的原始帖子中。处理出现/消失将节省与在整个地方添加代表相关的编码时间,因此最好先检查一下 - thx let anotherVC = self.storyboard?.instantiateInitialViewController() let navController = UINavigationController(rootViewController: anotherVC!) self.presentViewController(navController, animated: true, completion: nil) 您可能已将情节提要中 UINavigationController 上的 modalPresentationStyle 设置为 @Rikh 之前提到的 UIModalPresentationStyle.OverCurrentContext。我对此进行了测试,在这种情况下,您确实没有得到这些方法调用 感谢您清除这一点 - 两个潜在的控制器都将演示样式设置为全屏 - 等待其中一个以编程方式将其更改为自定义...... 很高兴你明白了 :)【参考方案3】:

首先,感谢 Serghei 抽出时间帮助解决这个问题。

为了澄清,我的两个潜在呈现的控制器在情节提要中都设置为全屏演示样式,但是通过一段处理演示的粘贴代码将一个设置为自定义。我找不到其他的错误。

但是,如果我在演示过程中强制使用全屏演示样式,那么一切正常。

希望我这个令人沮丧的下午可以帮助拯救其他人 - 始终尝试了解粘贴的 sn-ps 所涉及的含义和过程。

【讨论】:

以上是关于当 ViewController 被呈现的 ViewController 覆盖时触发事件的主要内容,如果未能解决你的问题,请参考以下文章

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

当用户按下主页按钮但在应用程序进入后台之前,如何从应用程序窗口的 rootViewController 呈现 viewController? [复制]

轻松实现部分背景半透明的呈现效果

从 SubView 呈现模态 ViewController

呈现新的 ViewController 后 Deinit UITabBarController

您将如何从子视图中呈现ViewController?