在Swift中制作NSWindowController Singleton的正确方法是什么?

时间:2016-12-04 21:33:18

标签: swift cocoa singleton nswindowcontroller nsstoryboard

我有一个示例项目:

https://github.com/ericgorr/nspanel_show.git

我的项目是基于文档的故事板应用程序。我想使用自定义segue来切换检查器窗口的可见状态。我有什么应该工作,但我不能确定如何使检查员窗口成为单身人士。

我相信我应该从:

开始
class InspectorWindowController: NSWindowController
{
    static let sharedInstance = InspectorWindowController()

//    override func init()
//    {
//        
//    }

    override func windowDidLoad()
    {
        super.windowDidLoad()

        NSLog( ":::: %@", InspectorWindowController.sharedInstance );
    }
}

但是在我的情况下,初始化应该是什么样子才能逃避我,特别是因为窗口在故事板内部。

2 个答案:

答案 0 :(得分:3)

以下是我修改代码的方法:

  1. Main.storyboard中为InspectorWindowController提供一个标识符,例如“Inspector Window Controller”
  2. InspectorWindowController中,按如下方式实施您的单身:

    static let shared: InspectorWindowController = {
        let storyboard = NSStoryboard(name:"Main", bundle: nil)
        let controller = storyboard.instantiateController(withIdentifier: "Inspector Window Controller")
        return controller as! InspectorWindowController
    }()
    
  3. Main.storyboard中删除WindowControllerInspectorWindowController

  4. 中的segue
  5. WindowController中将showMyPanel()hideMyPanel() IBActions替换为:

    @IBAction func toggleInspectorPanel( _ sender: AnyObject ) {
        let inspectorWindow = InspectorWindowController.shared.window!
        if inspectorWindow.isVisible {
            inspectorWindow.orderOut(self)
        } else {
            inspectorWindow.makeKeyAndOrderFront(self)
        }
    }
    
  6. 同样在WindowController中,从NSLog()移除windowDidLoad()来电。它会导致对InspectorWindowController.shared初始化代码的递归调用。

  7. Main.storyboard中,将“检查器”工具栏按钮链接到toggleInspectorPanel()
  8. InspectorWindowController.shared单例将被初始化,并且第一次引用检查器面板(但未显示)。

答案 1 :(得分:1)

您可以从窗口控制器场景中选择窗口控制器,然后在属性检查器中从Single下的弹出窗口中选择Presentation。这将确保show segue仅使用窗口控制器的单个实例。有关详细信息,请参阅this answer