【问题标题】:Opening a new window on a different storyboard在不同的故事板上打开一个新窗口
【发布时间】:2016-12-18 09:08:58
【问题描述】:

我正在开发一个带有故事板的 OS X 应用程序。我在带有自定义 ViewController 的匿名窗口上获得了带有入口点的 Preview.storyboard。在 AppDelegate 类中,我得到以下函数。

func newPreviewWindow(sender: AnyObject) {
    let storyboard = NSStoryboard.init(name: "Preview", bundle: nil)
    let initialController = storyboard.instantiateInitialController()
    initialController!.showWindow(nil)
    initialController!.makeKeyAndOrderFront(nil)
}

运行代码时,窗口显示,但我得到以下异常:

2016-08-11 10:27:12.434 MyApp[1090:290439] -[NSWindowController makeKeyAndOrderFront:]: unrecognized selector sent to instance 0x60000008c350
2016-08-11 10:27:12.434 MyApp[1090:290439] -[NSWindowController makeKeyAndOrderFront:]: unrecognized selector sent to instance 0x60000008c350
2016-08-11 10:27:12.440 MyApp[1090:290439] (
    0   CoreFoundation             0x00007fff926284f2 __exceptionPreprocess + 178
    1   libobjc.A.dylib            0x00007fff97c0ef7e objc_exception_throw + 48
    2   CoreFoundation             0x00007fff926921ad -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
    3   CoreFoundation             0x00007fff92598571 ___forwarding___ + 1009
    4   CoreFoundation             0x00007fff925980f8 _CF_forwarding_prep_0 + 120
    5   MyApp                      0x0000000100005617 
...

根据异常消息并在 Google 和 StackOverflow 上进行搜索,我尝试通过这种方式将 Selector 发送到 makeKeyAndOrderFront 函数:

func newPreviewWindow(sender: AnyObject) {
    let storyboard = NSStoryboard.init(name: "Preview", bundle: nil)
    let initialController = storyboard.instantiateInitialController()
    let selector = #selector(AppDelegate.newPreviewWindow(_:))
    initialController!.showWindow(nil)
    initialController!.makeKeyAndOrderFront(selector) // [A]
}

然后我在 [A] 行收到以下编译错误:Cannot call value of non-function type '((AnyObject?) -> Void)!'

如何正确打开新窗口或通过Selector?

谢谢! :)

【问题讨论】:

    标签: swift macos cocoa storyboard selector


    【解决方案1】:

    initialController!.makeKeyAndOrderFront(nil) 导致问题,因为makeKeyAndOrderFront: 不是NSWindowController 方法 - 它属于NSWindow(因此出现无法识别的选择器错误)。将初始控制器转换为 NSWindowController 子类,然后通过控制器的 window 属性将窗口置于最前面:

    var windowController: NSWindowController!
    
    @IBAction func showOtherWindow(sender: AnyObject) {
        windowController = storyboard.instantiateInitialController() as! NSWindowController
        windowController.window?.makeKeyAndOrderFront(nil)
    }
    

    【讨论】:

    • 非常感谢!它似乎修复了异常和编译错误。不幸的是,该窗口根本没有显示(奇怪的是在initialController!.makeKeyAndOrderFront(nil) 上引发异常时它的显示方式)。我同时执行windowController.showWindow(nil)windowController.window!.makeKeyAndOrderFront(nil) 并且没有任何反应。你会知道为什么吗?
    • 在您发布的代码中,initialController 是一个局部变量。像任何其他局部变量一样,一旦创建它的函数退出,它就会丢失(连同窗口一起)。换句话说,窗口确实出现,但仅在函数执行之前出现;这发生得如此之快,以至于看起来什么都没有发生。在您的崩溃代码中,崩溃可能具有暂停或冻结函数执行的效果。结果,该函数永远不会返回,并且窗口控制器会留在周围以保持窗口在屏幕上。解决方案是将控制器分配给一个属性。
    • 哦,我明白了!它现在完美运行,并且由于我的 java 背景,我已经掌握了两个我还不理解的重要概念!非常感谢!!
    • 你真的应该使用showWindow()而不是makeKeyAndOrderFront()。前者在适当的时候执行后者,并且不需要您访问窗口即可。
    猜你喜欢
    • 2017-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-01
    • 1970-01-01
    • 2021-07-24
    相关资源
    最近更新 更多