如何将堆栈中的 1 个以上的视图控制器委托给视图控制器?
How do I delegate to view controller more than 1 view controller up the stack?
场景:我有一个视图控制器 (vc1),它呈现另一个视图控制器 (vc2)。然后 vc2 呈现 vc3。如何将 vc1 设置为 vc3 的代表?
情况:在vc3中,我打算跳回vc1并让它执行一些代码。但是,由于 vc3 实例是在 vc2 中创建的,因此 vc1 没有 direct link 到 vc3 来自 vc1.
这是我要实现的目标的简化图:
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 的)?将代表从 vc3 链接到 vc2 然后到 vc1 是唯一的出路吗?我想当中间有几个 vc 时,这会很难看。
有两种方法,一种是委托,另一种是通知。
委派:
正如你所问,你正在尝试这个。只是:
- 在 vc2 和 vc3 中创建一个委托变量。
- 在 vc1 中创建 vc2 的对象时,在 vc2 的委托变量中传递
self
。
- 在 vc2 中创建 vc3 的对象时,在 vc3.
的委托变量中传递 self.delegate
- 现在,当您调用 vc3 中的方法时,例如
self.delegate?.anyMethod()
将在 vc2 和 vc3 中得到调用。
通知:
从通知开始,您可以广播自定义类型的通知,其中包含 vc3 的一些信息。并且可以添加观察者以观察 vc1 或任何其他 vc 中的通知,您将收到带有传递数据的调用。
详细了解通知 here
作为我个人的建议,第一个更适合你的情况。
您可以通过多种方式实现这一目标。下面列出了其中一些。
如果 VC1 是导航堆栈的根 VC,您可以使用
在 VC3
中低于 API
popToRootViewController(动画:)
您可以通过其他方式获取 viewControllers 数组 属性
navigationController 并从数组中获取 VC1 并使用
在 VC3
中低于 API
popToViewController(_:animated:)
希望对您有所帮助。有疑问请评论。
场景:我有一个视图控制器 (vc1),它呈现另一个视图控制器 (vc2)。然后 vc2 呈现 vc3。如何将 vc1 设置为 vc3 的代表?
情况:在vc3中,我打算跳回vc1并让它执行一些代码。但是,由于 vc3 实例是在 vc2 中创建的,因此 vc1 没有 direct link 到 vc3 来自 vc1.
这是我要实现的目标的简化图:
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 的)?将代表从 vc3 链接到 vc2 然后到 vc1 是唯一的出路吗?我想当中间有几个 vc 时,这会很难看。
有两种方法,一种是委托,另一种是通知。
委派:
正如你所问,你正在尝试这个。只是:
- 在 vc2 和 vc3 中创建一个委托变量。
- 在 vc1 中创建 vc2 的对象时,在 vc2 的委托变量中传递
self
。 - 在 vc2 中创建 vc3 的对象时,在 vc3. 的委托变量中传递
- 现在,当您调用 vc3 中的方法时,例如
self.delegate?.anyMethod()
将在 vc2 和 vc3 中得到调用。
self.delegate
通知:
从通知开始,您可以广播自定义类型的通知,其中包含 vc3 的一些信息。并且可以添加观察者以观察 vc1 或任何其他 vc 中的通知,您将收到带有传递数据的调用。 详细了解通知 here
作为我个人的建议,第一个更适合你的情况。
您可以通过多种方式实现这一目标。下面列出了其中一些。
如果 VC1 是导航堆栈的根 VC,您可以使用 在 VC3
中低于 APIpopToRootViewController(动画:)
您可以通过其他方式获取 viewControllers 数组 属性 navigationController 并从数组中获取 VC1 并使用 在 VC3
中低于 APIpopToViewController(_:animated:)
希望对您有所帮助。有疑问请评论。