【问题标题】:How do I delegate to view controller more than 1 view controller up the stack?如何在堆栈中将超过 1 个视图控制器委托给视图控制器?
【发布时间】:2019-01-06 11:00:08
【问题描述】:

场景:我有一个视图控制器 (vc1),它呈现另一个视图控制器 (vc2)。然后vc2呈现vc3。如何将 vc1 设置为 vc3 的委托?

情况:在 vc3 中,我打算跳回 vc1 并让它执行一些代码。但是,由于 vc3 实例是在 vc2 中创建的,所以 vc1 没有从 vc1 到 vc3 的直接链接。

这是我要实现的目标的简化图:

vc1

let vc2Instance = vc2()
navigationController?.pushViewController(vc2Instance)

class vc1: UIViewController, tellVC1ToDoSomethingDelegate {

    func vc1DoSomething(withThis: String) {
        // for instance: present another VC not currently in stack
        let randomVC = RandomVC()
    }
}

vc2

let vc3Instance = vc3()
navigationController?.pushViewController(vc3Instance)

vc3

protocol tellVc1ToDoSomethingDelegate() {
   func vc1DoSomething(withThis: String)
}

class vc3: UIViewController {
   weak var vc1Delegate: tellVC1ToDoSomethingDelegate?

   func pushRandomVCWithString(myString: String) {
      // code to dismiss view controllers up to vc1 in stack
      if let vcStack = self.navigationController?.viewControllers{
          self.navigationController?.popToViewController(vcStack[vcStack.count - 2], animated: true)

      vc1Delegate.vc1DoSomething(withThis: myString)
   }
}

这是我的问题: 如果我将 vc1 标记为 vc2 的委托(堆栈中只有 1 个 VC),我只需键入

let vc2Instance = vc2()
vc2Instance.vc1Delegate = self

当 vc1 中不存在 vc3 的实例时,我如何访问(vc1 的)self?将代表从 vc3 链接到 vc2 然后到 vc1 是唯一的出路吗?我想当中间有几个 vc 时这会很难看。

【问题讨论】:

  • 你可以做委托链接,从 vc1 -> vc2 -> vc3 传递委托,然后 vc3 可以调用该委托并关闭 vc2 和 vc3

标签: ios swift delegates viewcontroller


【解决方案1】:

有两种方法,一种是委托,另一种是通知。

  1. 代表团:

    正如你所问,你正在尝试这个。只是:

    • 在 vc2 和 vc3 中都创建一个委托变量。
    • 在 vc1 中创建 vc2 的对象时,在 vc2 的委托变量中传递 self
    • 在 vc2 中创建 vc3 的对象时,在 vc3 的委托变量中传递 self.delegate
    • 现在,当您在 vc3 中调用 self.delegate?.anyMethod() 之类的方法时,将在 vc2 和 vc3 中都得到调用。
  2. 通知:

    作为通知,您可以广播自定义类型的通知,其中包含一些 vc3 的信息。并且可以在 vc1 或任何其他 vc 中添加观察者来观察通知,您将收到带有传递数据的调用。 了解更多关于通知here

根据我的个人建议,第一个对你来说更好。

【讨论】:

  • 我最终使用了通知,它们运行良好。我中间有大约 3 个 vc,感觉一直链接起来效率低下
【解决方案2】:

您可以通过多种方式实现这一目标。下面列出了其中一些。

  1. 如果 VC1 是导航堆栈的根 VC,则可以使用 VC3下面的API

    popToRootViewController(动画:)

  2. 您可以通过其他方式从 navigationController 并从数组中获取 VC1 并使用 VC3下面的API

    popToViewController(_:animated:)

希望对您有所帮助。如有疑问请评论。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-01
    • 2023-03-08
    • 1970-01-01
    相关资源
    最近更新 更多