UIViewController 包含通知

Posted

技术标签:

【中文标题】UIViewController 包含通知【英文标题】:UIViewController containment notifications 【发布时间】:2018-09-28 15:18:16 【问题描述】:

我对 UIViewController 的遏制有疑问。为简单起见,我制作了一个示例项目并定义了 SecondViewController 类。

class SecondViewController: UIViewController 

override func viewDidLoad() 
    super.viewDidLoad()
    self.view.backgroundColor = UIColor.black
    NSLog("In second controller")

    // Do any additional setup after loading the view.


override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) 
    NSLog("Transitioning in second controller")
  
 

在第一个控制器中,我执行以下操作:

class ViewController: UIViewController 

override func viewDidLoad() 
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    let secondController = SecondViewController()
    addChild(secondController)
    view.addSubview(secondController.view)
    secondController.view.frame = self.view.bounds
    secondController.didMove(toParent: self)


override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) 
    NSLog("Transitioning in first controller")
   
 

当我运行程序时,它会运行并且日志如下:

2018-09-28 19:11:15.491211+0400 ViewContainment[3897:618645] In second controller
2018-09-28 19:11:17.254221+0400 ViewContainment[3897:618645] Transitioning in first controller

问题:

    这是否意味着所有 UIViewController 通知都将由第一个视图控制器处理,并且不会向第二个视图控制器发送任何通知?

    将第二个视图控制器中的按钮单击操作添加到第一个视图控制器中的选择器是否安全?

【问题讨论】:

【参考方案1】:

来自 Apple 的文档 (https://developer.apple.com/documentation/uikit/uicontentcontainer/1621511-willtransition):

如果您在自己的对象中覆盖此方法,请始终在您的实现中调用 super ,以便 UIKit 可以将 trait 更改转发到关联的表示控制器和任何子视图控制器。 视图控制器将特征更改消息转发给它们的子视图控制器。

所以请确保您在ViewController 中的函数这样做:

override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) 
    super.willTransition(to: newCollection, with: coordinator)
    NSLog("Transitioning in first controller")


问题 2:否。使用协议/委托模式允许子视图控制器中的操作与父视图控制器中的函数/方法进行通信。

【讨论】:

Ok trait 更改仅用于示例,但所有 UIViewController 消息/通知是否都通过调用 super 传达给子视图控制器? 不......但这有点无关紧要。 应该调用 super 的方法/通知应该这样做,无论您是否使用包含控制器。 我有一个 UIViewController,我通过包含添加了第二个视图控制器。键值观察在第一个视图控制器中继续,因为我不希望代码重复和删除/读取键值观察者和处理程序。解决这种情况的干净方法是什么?

以上是关于UIViewController 包含通知的主要内容,如果未能解决你的问题,请参考以下文章

为啥 UIPopoverController 不是 UIViewController 的子类?

在 UIViewController 中创建整个 UIView

以编程方式向 UIView 或 UIViewController 添加约束?

Interface Builder 是如何知道 UIViewController 的视图的?

如何在 SwiftUI 中使用 UIViewController 和 UIView?

在 UIViewController 的主视图中加载自定义 UIView