无法使用情节提要自定义实例化窗口控制器 [英] Can't use storyboard custom instantiated window controller

查看:92
本文介绍了无法使用情节提要自定义实例化窗口控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试从情节提要中自定义实例化窗口控制器时,我遇到了感觉像是个错误的错误.我正在使用NSStoryboard.instantiateController(identifier:creator:),这是MacOS 10.15中的新功能.有问题的代码块是:

I am getting what feels like a bug when trying to custom instantiate a window controller from a storyboard. I am using NSStoryboard.instantiateController(identifier: creator: ), which is a new function as of MacOS 10.15. The block of code in question is:

Let mainWindowController = storyboard.instantiateController(identifier: "Analysis Window Controller") { aDecoder in  
            MainWindowController(coder: aDecoder)  
        } 

我已经成功地使用了这个确切的代码来自定义实例化主 view 控制器,并将该视图分配给一个新窗口和一个新的窗口控制器.很好我还可以使用老式的方式实例化 window 控制器,而无需使用InstantiateController(identifier :)进行自定义初始化.但是,当我尝试上述代码用于 window 控制器的 custom 实例化时,我最终遇到以下错误:

I have SUCCESSFULLY used basically this exact code for custom instantiating the main view controller, and just assigning that view to a new window and a new window controller. That works fine. I can also instantiate the window controller the old fashioned way without custom initialization with instantiateController(identifier:). But when I try the above code for custom instantiation of the window controller I end up with the following error:

-[NSClassSwapper _createControllerForCreator:coder:]中的断言失败...自定义实例化控制器必须调用-[super initWithCoder:]

Assertion failure in -[NSClassSwapper _createControllerForCreator:coder:]...Custom instantiated controller must call -[super initWithCoder:]

请注意,我的自定义视图控制器类(有效)和我的自定义窗口控制器类MainWindowController(均无效)都实现了简单的初始化程序:

Note that both my custom view controller class (which works) and my custom window controller class MainWindowController (which doesn't work) have implemented the trivial initializer:

  required init?(coder: NSCoder) {  
        super.init(coder: coder)  
    }  

我知道此功能自OS 10.15起是新功能,但文档说,它应该适用于窗口控制器和视图控制器,并且该错误消息对我来说没有任何意义.

I know that this functionality is new as of OS 10.15, but the documentation says it should work for window controllers AND view controllers, and the error message does not make any sense to me.

推荐答案

我遇到了同样的问题,我想了一下,这就是我的解决方法.

I hit the same problem, I thought about it a bit and here is how I worked around it.

首先,为什么需要这个?我想在从Storyboard构建视图控制器之前将一些依赖项注入到我的视图控制器层次结构中.我想这就是API的目的. 但是,那该方法是否可行,我该如何将注入信息向下传递到视图控制器层次结构中?

First, why do I need this for ? I wanted to inject some dependencies to my view controller hierarchy before it's built from the Storyboard. I guess that's what the API is intended to. But then, would that method be working, how would I pass the injection information down the view controller hierarchy ?

因此,由于该方法在视图控制器中运行时没有错误,因此我决定直接在根视图控制器中注入信息.

So, as the method is working without bug for view controllers, I decided to inject the information directly at the root view controller.

所以,我在故事板中:

  • 一个名为"my-window-controller"的窗口控制器场景,该窗口仅指向一个空的视图控制器.
  • 一个名为"root-view-controller"的视图控制器场景,其中描述了所有视图层次结构.

在我想创建该视图控制器的任何地方,我都要做:

And wherever I want to create that view controller, I just do :

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

这篇关于无法使用情节提要自定义实例化窗口控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆