ios - 我可以将私有(private)变量传递给将通过 Storyboard 实例化的 UIViewController 吗?

标签 ios swift uiviewcontroller arguments init

我有一个“根”UIViewController,它本身实例化了另外两个 UIViewController。然而,我需要将一些东西传递给它们中的每一个,这必须在初始化时完成。

但是

所有 3 个 UIViewController 都是通过 Storyboard实例化的。

这可能吗?或者我应该看看其他一些设计模式来传递这些数据吗?

具体来说,我试图避免紧密耦合,但是“根”实例化的 2 个 UIViewController 彼此不了解,但在两者中,都需要知道它们的值一个变量。

可以使这个变量在“根”上成为静态变量,但这会强制耦合。

我可以制作一个全局“常量”swift 文件并将变量放在那里,但这看起来很脏而且很老套。

理想情况下,我想在实例化时将此变量传递给这些 UIViewController 中的每一个,但由于它们都是从 Storyboard 加载的,所以我无法让它工作。

我看过关于类似事情的博客和堆栈帖子,例如

https://blog.scottlogic.com/2014/11/20/swift-initialisation.html

但我还没有看到一个决定性的方法。

我是不是用错了方法?

下面的“示例”代码显然不起作用,但它可以向您展示我正在尝试做的事情,当然条件是所有这三个 UIViewControllers 都有一个条目Interface Builder 并使用 Storyboard 中的那些进行实例化...

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:) ,这使您有机会在目标 View Controller 中设置属性。如果你想让它们保持松散耦合,你可以使用一个协议(protocol):

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
    }
}

显然,您会给您的协议(protocol)取一个更有意义的名称,但我们可能想更多地了解该应用程序以提出更好的建议。

关于ios - 我可以将私有(private)变量传递给将通过 Storyboard 实例化的 UIViewController 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57340179/

相关文章:

ios - (Swift)当多个 View Controller 导致相同 View 时放松 segue?

objective-c - 通过 SSH 从 iOS 远程重新启动/关闭 mac?

ios - 收到 CKDatabaseNotification 后查询变化

iphone - Storyboards VS xib 的使用理念

iphone - viewDidLoad 实际上是在每次有 segue 转换时调用的

iOS如何让用户注册账号/如何做用户数据库

ios - 数组包含对象问题

ios - 类型 'UIViewController' 的值没有成员 'addSubview' Swift2

ios - 我想在点击它时更改 UIButton 图像

ios - 为什么 UIView 比 Screen 宽