我有一个“根” UIViewController,它本身实例化了另外两个UIViewControllers。但是,我需要将一些内容传递给每个步骤,这必须在初始化时完成。
但
所有3个UIViewController都是通过Storyboard实例化的。
这可能吗?还是我应该看看其他设计模式来传递这些数据?
具体来说,我正在尝试避免紧密耦合,但是“root”实例化的2个UIViewControllers彼此不了解,但是两者都要求它们知道变量的值。
我可以将此变量设为“根”上的静态变量,但这会强制耦合。
我可以制作一个全局“常量”快速文件,然后将变量放在其中,但这似乎很脏而且很hacky。
理想情况下,我想在实例化时将此变量传递到每个UIViewController中,但是由于它们都是从Storyboard加载的,因此无法正常工作。
我看过博客和有关类似内容的帖子,例如
https://blog.scottlogic.com/2014/11/20/swift-initialisation.html
但是我还没有一个结论性的方法。
我会以错误的方式处理吗?
下面的“示例”代码显然无法正常工作,但它在那里向您展示我正在尝试做的事情,当然,条件是所有这三个UIViewControllers在Interface Builder中都有一个条目,并使用来自故事板...
class root : UIViewController
{
private let a: CGFloat = 1.0
private let b: CGFloat = 10.0
private let vc1: firstViewController
private let vc2: secondViewController
override init()
{
self.vc1 = firstViewController(a: a, b: b)
self.vc2 = secondViewController(a: a, b: b)
super.init
}
}
class firstViewController : UIViewController
{
private let a: CGFloat
private let b: CGFloat
init(a: CGFloat, b: CGFloat)
{
self.a = a
self.b = b
super.init(aDecoder: Decoder)
}
}
这也取决于如何“链接” UIViewController实例化...我还没有找到博客或教程或说明。
感谢您的帮助/建议。
最佳答案
典型的解决方案是实现 prepare(for:sender:)
,这使您有机会在目标视图控制器中设置属性。如果要保持它们松散耦合,可以使用一个协议:
protocol DataDestination {
var a: CGFloat? { get set }
var b: CGFloat? { get set }
}
class RootViewController: UIViewController {
private let a: CGFloat = 1.0
private let b: CGFloat = 10.0
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? DataDestination {
destination.a = a
destination.b = b
}
}
}
class FirstViewController: UIViewController, DataDestination {
var a: CGFloat?
var b: CGFloat?
override func viewDidLoad() {
super.viewDidLoad()
print(a,b) // by the time we hit this, those will be set
}
}
显然,您可以给您的协议起一个更有意义的名称,但是我们可能想更多地了解该应用程序,以便提出更好的建议。
关于ios - 我可以将私有(private)变量传递到将通过 Storyboard 实例化的UIViewController吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57340179/