无法使用故事板自定义实例化 window 控制器
Can't use storyboard custom instantiated window controller
我在尝试从情节提要中自定义实例化 window 控制器时感觉像是一个错误。我正在使用 NSStoryboard.instantiateController(identifier:creator:)
,这是 MacOS 10.15 的新功能。有问题的代码块是:
let mainWC = storyboard.instantiateController(identifier: "id") { aDecoder in
MainWindowController(coder: aDecoder)
}
我基本上成功地使用了这个确切的代码来自定义实例化主 view 控制器,并将该视图分配给新的 window 和新的 window 控制器。那很好用。我还可以用老式的方式实例化 window 控制器,而无需使用 instantiateController(identifier:)
进行自定义初始化。但是,当我尝试使用上述代码对 window 控制器进行 custom 实例化时,我最终遇到以下错误:
Assertion failure in -[NSClassSwapper _createControllerForCreator:coder:]
... Custom instantiated controller must call -[super initWithCoder:]
请注意,我的自定义视图控制器 class(有效)和自定义 window 控制器 class MainWindowController
(无效)都实现了琐碎的初始值设定项:
required init?(coder: NSCoder) {
super.init(coder: coder)
}
我知道这个功能是 OS 10.15 的新功能,但是 documentation 说它应该适用于 window 控制器和视图控制器,并且错误消息不会对我来说有什么意义。
这已作为反馈 #FB7626059 归档,如果您想继续(我也遇到了这个问题)。
我遇到了同样的问题,我想了一下,这是我解决它的方法。
首先,我为什么需要这个?在从 Storyboard 构建之前,我想向我的视图控制器层次结构注入一些依赖项。我想这就是 API 的目的。
但是,该方法是否有效,我将如何将注入信息传递到视图控制器层次结构中?
因此,由于该方法在视图控制器中没有错误,我决定直接在根视图控制器中注入信息。
所以,我的故事板中有:
- 一个名为 "my-window-controller" 的 window 控制器场景,window 只是指向一个空的视图控制器。
- 一个名为 "root-view-controller" 的视图控制器场景,其中描述了所有视图层次结构。
无论我想在何处创建视图控制器,我都可以这样做:
func instanciateWindowController(storyboard: NSStoryboard) -> NSWindowController {
// Load the (empty) window controller scene
let wcSceneIdentifier = NSStoryboard.SceneIdentifier("my-window-controller")
let windowController = storyboard.instantiateController(withIdentifier: wcSceneIdentifier)
as! NSWindowController
// Load the root view controller using the creator trick to inject dependencies
let vcSceneIdentifier = NSStoryboard.SceneIdentifier("root-view-controller")
let viewController = storyboard.instantiateController(identifier: vcSceneIdentifier,
creator: { coder in
return MyOwnViewController.init(coder: coder,
text: "Victoire !") // just pass here your injection info
})
// Associate the window controller and the root view controller
windowController.contentViewController = viewController
return windowController
}
和
class MyOwnViewController: MSViewController {
init?(coder: NSCoder,
text: String) { // receive here the injection information
print(text) // use the injection information here
super.init(coder: coder)
}
// Not used, but required
required init?(coder: NSCoder) {
super.init(coder: coder)
}
}
我在尝试从情节提要中自定义实例化 window 控制器时感觉像是一个错误。我正在使用 NSStoryboard.instantiateController(identifier:creator:)
,这是 MacOS 10.15 的新功能。有问题的代码块是:
let mainWC = storyboard.instantiateController(identifier: "id") { aDecoder in
MainWindowController(coder: aDecoder)
}
我基本上成功地使用了这个确切的代码来自定义实例化主 view 控制器,并将该视图分配给新的 window 和新的 window 控制器。那很好用。我还可以用老式的方式实例化 window 控制器,而无需使用 instantiateController(identifier:)
进行自定义初始化。但是,当我尝试使用上述代码对 window 控制器进行 custom 实例化时,我最终遇到以下错误:
Assertion failure in
-[NSClassSwapper _createControllerForCreator:coder:]
... Custom instantiated controller must call-[super initWithCoder:]
请注意,我的自定义视图控制器 class(有效)和自定义 window 控制器 class MainWindowController
(无效)都实现了琐碎的初始值设定项:
required init?(coder: NSCoder) {
super.init(coder: coder)
}
我知道这个功能是 OS 10.15 的新功能,但是 documentation 说它应该适用于 window 控制器和视图控制器,并且错误消息不会对我来说有什么意义。
这已作为反馈 #FB7626059 归档,如果您想继续(我也遇到了这个问题)。
我遇到了同样的问题,我想了一下,这是我解决它的方法。
首先,我为什么需要这个?在从 Storyboard 构建之前,我想向我的视图控制器层次结构注入一些依赖项。我想这就是 API 的目的。 但是,该方法是否有效,我将如何将注入信息传递到视图控制器层次结构中?
因此,由于该方法在视图控制器中没有错误,我决定直接在根视图控制器中注入信息。
所以,我的故事板中有:
- 一个名为 "my-window-controller" 的 window 控制器场景,window 只是指向一个空的视图控制器。
- 一个名为 "root-view-controller" 的视图控制器场景,其中描述了所有视图层次结构。
无论我想在何处创建视图控制器,我都可以这样做:
func instanciateWindowController(storyboard: NSStoryboard) -> NSWindowController {
// Load the (empty) window controller scene
let wcSceneIdentifier = NSStoryboard.SceneIdentifier("my-window-controller")
let windowController = storyboard.instantiateController(withIdentifier: wcSceneIdentifier)
as! NSWindowController
// Load the root view controller using the creator trick to inject dependencies
let vcSceneIdentifier = NSStoryboard.SceneIdentifier("root-view-controller")
let viewController = storyboard.instantiateController(identifier: vcSceneIdentifier,
creator: { coder in
return MyOwnViewController.init(coder: coder,
text: "Victoire !") // just pass here your injection info
})
// Associate the window controller and the root view controller
windowController.contentViewController = viewController
return windowController
}
和
class MyOwnViewController: MSViewController {
init?(coder: NSCoder,
text: String) { // receive here the injection information
print(text) // use the injection information here
super.init(coder: coder)
}
// Not used, but required
required init?(coder: NSCoder) {
super.init(coder: coder)
}
}