如何使用它的编码器从故事板初始化 ViewController
我意识到这可能很难实现,但我希望能够使用 init(coder: NSCoder)
从 storyboard
初始化 ViewControllers
直接运行。我的意思是不使用 storyboard.instantiateViewController(identifier: coder: )
- 我知道我可以使用它,但这是我想跳过的。相反,我更愿意在 ViewController 中有一个 init,如下所示: init(viewModel: ViewModel)
并使用此 init 从 storyboard
初始化此 ViewController
。在这个初始化中,我想象有某种机制可以打开我的故事板,并以某种方式提取它的编码器,以便我可以编写:
static let storyboard = UIStoryboard(named: "Game")
private let viewModel: ViewModel
init(viewModel: ViewModel) {
self.viewModel = viewModel
let identifier = String(describing: Self.self)
let coder: NSCoder = Self.storyboard.somehowGetTheCoderForViewController(withId: identifier)
super.init(coder: coder)
}
问题是如何以我能够获得的方式读取故事板特定 ViewController 的编码器。 再次 - 我知道这可以通过使用类似的东西来解决
storyboard.instantiateViewController(identifier: String(describing: Self.self)) { coder in
Self.init(coder: coder, viewModel: viewModel)
}
,但我正在寻找一种不使用 instantiateViewController
的方法,而只是能够获取 coder
,以便稍后我可以像这样启动
VC:
let viewController = ViewContorller(viewModel: viewModel)
所以问题是如何解压storyboard
,并检索某些ViewController
coder对象代码>.
I realize that this might be difficult to achieve, but I would like to be able to initialize ViewControllers
from storyboard
using init(coder: NSCoder)
function directly. I mean not using storyboard.instantiateViewController(identifier: coder: )
- I know I could use this, but this is what I would like to skip. Instead I would prefer to have a init in ViewController
like this:init(viewModel: ViewModel)
and use this init to initialize this ViewController
from the storyboard
. Inside this init I imagine having some mechanism that would open my storyboard
, and extracted it's coder somehow, so that I could write:
static let storyboard = UIStoryboard(named: "Game")
private let viewModel: ViewModel
init(viewModel: ViewModel) {
self.viewModel = viewModel
let identifier = String(describing: Self.self)
let coder: NSCoder = Self.storyboard.somehowGetTheCoderForViewController(withId: identifier)
super.init(coder: coder)
}
Problem is how to read storyboard in such a way that I was able to get the coder of particular ViewController from it.
Again - I know this can be solved by using something like this
storyboard.instantiateViewController(identifier: String(describing: Self.self)) { coder in
Self.init(coder: coder, viewModel: viewModel)
}
But Im looking for a way to not use instantiateViewController
, and just be able to get the coder
, so that later I could just initiate
VC like this:
let viewController = ViewContorller(viewModel: viewModel)
So the question is how to unpack storyboard
, and retrieve coder
object for some ViewController
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你不应该这样做。
作为
init(nibName:bundle:)
的文档 说:使用初始化程序初始化 VC 时,您应该使用初始化程序,而不是 init(coder:)。如果您使用故事板,那么您应该使用instantiateViewController,或者使用segues来获取新的VC。
因此,要实现此语法:
您可以将 VC 放入 xib 文件中,然后执行以下操作:
如果必须使用故事板,则不能使用初始化语法来初始化 VC。您可以改为创建一个工厂方法,例如:
并使用
UIStoryboard.instantiateViewController
实现它。You are not supposed to do this.
As the documentation of
init(nibName:bundle:)
says:When initialising a VC using an initialiser, that initialiser is what you should use, not
init(coder:)
. If you use storyboards, then you should useinstantiateViewController
, or use segues to get new VCs.So to achieve this syntax:
You can put your VCs in xib files, and do:
If you must use storyboards, then you can't use an initialiser syntax for initialising VCs. You can instead make a factory method, such as:
And implement it using
UIStoryboard.instantiateViewController
.这就是初始化器
instantiateViewController(identifier:creator:)
存在的原因。https://developer.apple.com/documentation/uikit/uistoryboard/3213989- instantiateviewcontroller
您收到
coder
并使用它来调用自定义初始值设定项,该初始值设定项本身会调用coder
初始化程序还执行其他自定义初始化。为了说明这一点,假设我们有一个 ViewController 类,其中包含一个
message
String 属性,当视图出现时,该类将在 UILabel 中呈现给用户。因此,我们为 ViewController 提供了一个init(coder:message:)
初始化程序:留给它自己的设备,但是,运行时永远不会调用我们的
init(coder:message:)
初始化器;它对此一无所知!运行时知道从故事板实例化视图控制器的唯一方法是调用init(coder:)
。但是当我们从故事板实例化视图控制器时,我们可以调用 init(coder:message:) 。假设这是故事板的初始视图控制器,我们在启动时在场景委托中调用它:
我们调用
instantiateViewController(identifier:creator:)
和creator:
函数调用init(coder:message:)
— 而后者又调用init(coder:)
。因此,我们对creator:
函数的使用是合法的,并且视图显示正确。This is why the initializer
instantiateViewController(identifier:creator:)
exists.https://developer.apple.com/documentation/uikit/uistoryboard/3213989-instantiateviewcontroller
You receive the
coder
and use it to call a custom initializer that itself calls thecoder
initializer but also does other custom initialization.To illustrate, suppose we have a ViewController class with a
message
String property to be presented to the user in a UILabel when the view appears. So we've given ViewController aninit(coder:message:)
initializer:Left to its own devices, however, the runtime will never call our
init(coder:message:)
initializer; it knows nothing of it! The only way the runtime knows to instantiate a view controller from a storyboard is by callinginit(coder:)
. But we can callinit(coder:message:)
when we instantiate the view controller from the storyboard.Suppose this is the storyboard's initial view controller, and we're calling it in the scene delegate at launch time:
We call
instantiateViewController(identifier:creator:)
and thecreator:
function callsinit(coder:message:)
— which, in turn, callsinit(coder:)
. Thus our use of thecreator:
function is legal, and the view appears correctly.