【问题标题】:iOS Responder Chain and EventsiOS 响应者链和事件
【发布时间】:2020-05-15 09:23:02
【问题描述】:

我有点困惑。 UINavagationController 的堆栈中有两个 UIViewControllers。我尝试在 second UIViewController 内调用 first UIViewController 的方法。见下面的代码

class VC1: UIViewController {

    @objc func method1() {
        //not called after tap button
    }
}

class VC2: UIViewController {

    let button = UIButton()

    override func viewDidLoad() {
        super.viewDidLoad()

        button.addTarget(nil, action: #selector(VC1.method1), for: .touchUpInside)
    }
}

但是当我点击按钮时不会调用 method1。有什么问题?

【问题讨论】:

    标签: swift uiresponder uievent


    【解决方案1】:

    响应者链基于超级视图和父视图控制器。所以 VC1 不是 VC2 的响应者链。来自 VC2 的响应者链通向其父级(UINavigationController);它不会通过 UINavigationController 的任何其他子级。

    【讨论】:

      【解决方案2】:

      响应者链,从button 开始,经过button 的祖先视图和视图控制器。由于 VC1 和 VC2 是导航控制器堆栈中的独立项,因此 VC1 不是 VC2 的祖先。他们更像是彼此的兄弟姐妹。所以VC1不在button的响应者链中。

      您可以将 VC1 设置为按钮操作的目标:

      let vc1: VC1 = ...
      button.addTarget(vc1, action: #selector(VC1.method1), for: .touchUpInside)
      

      但这意味着 VC2 需要引用现有的 VC1 实例。你怎么得到那个参考?这取决于您如何创建 VC2 并将其推送到导航堆栈。

      如果 VC1 在代码中创建 VC2,则 VC1 在创建 VC2 时只需为新 VC2 提供对 self(VC1)的引用。

      如果你有一个来自 VC1 的故事板 segue 将 VC2 推入堆栈,那么你需要在 VC1 中实现 prepare(for: UIStoryboardSegue, sender:),并且在该方法中你需要将 self (VC1) 传递到 segue 的目的地( VC2)。

      【讨论】:

        【解决方案3】:
        • push的时候,pushViewController和navigationController的关系。
        • 当您以模态方式呈现时,presentedViewControllerUIWindow 之间存在关系。可以理解,呈现和呈现的视图控制器之间存在关系,但这只是它们相互引用的问题。他们没有通过响应者链管道连接起来......
        • 只有当一个 viewController 成为另一个 ViewController 的 childViewController 时,它们的响应器链才会以您认为的方式挂钩,这意味着 childViewController 的 nextResponder 成为它的“parentViewController”

        ——

        来自nextResponder docs

        例如,UIView 实现了这个方法并返回 管理它的 UIViewController 对象(如果有的话)或其 superview(如果没有)。 UIViewController 类似地实现了 方法并返回其视图的父视图。 UIWindow 返回 应用对象。共享的 UIApplication 对象通常返回 nil,但如果该对象是 UIResponder 并且尚未被调用来处理事件。

        读到这里我们知道presentingViewController和pushViewController都不是viewController的superview

        【讨论】:

          猜你喜欢
          • 2011-01-15
          • 1970-01-01
          • 1970-01-01
          • 2014-12-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多