如何委派视图控制器到堆栈中的多个视图控制器?

时间:2018-07-30 08:24:43

标签: ios swift delegates viewcontroller

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

情况:在vc3中,我打算弹出vc1并让其执行一些代码。但是,由于vc3实例是在vc2中创建的,因此vc1没有从vc1到vc3的 direct 链接。

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

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的委托(仅将VC放在堆栈中),我将简单地输入

let vc2Instance = vc2()
vc2Instance.vc1Delegate = self

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

2 个答案:

答案 0 :(得分:1)

有两种方法,一种是委派,另一种是Notification。

  1. 委托:

    按照您的要求,您正在尝试此。只是:

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

    从通知开始,您可以广播自定义类型的通知以及有关vc3的一些信息。并且可以在vc1或任何其他vc中添加观察者以观察通知,您将收到包含传递数据的呼叫。 了解有关通知here

  3. 的更多信息

根据我个人的建议,在您的情况下,第一个更好。

答案 1 :(得分:0)

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

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

    popToRootViewController(动画:)

  2. 通过其他方法可以从中获取viewControllers数组属性 navigationController并从数组中获取VC1并使用 低于VC3中的API

    popToViewController(_:animated:)

希望此帮助。请发表任何疑问。