无法使用故事板自定义实例化 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)
    }
}