可可Xcode:使用Swift 4 for Mac从AppDelegate编程打开窗口控制器?

3xiyfsfu  于 2023-06-24  发布在  Swift
关注(0)|答案(2)|浏览(124)

我正在制作一个简单的菜单栏应用程序,其中有2个项目-首选项&退出
我想在点击首选项时打开一个新窗口
目前我有

func applicationDidFinishLaunching(_ aNotification: Notification) {
        constructMenu()
    }

func constructMenu() {
        let menu = NSMenu()

        menu.addItem(NSMenuItem(
                       title: "Preferences...", 
                       action: #selector(AppDelegate.preferencesWindow(_:)), 
                       keyEquivalent: "P"))
        menu.addItem(NSMenuItem.separator())
        menu.addItem(NSMenuItem(
                       title: "Quit", 
                       action: #selector(NSApplication.terminate(_:)), 
                       keyEquivalent: "q"))

        statusItem.menu = menu
    }

@objc func preferencesWindow(_ sender: Any) {
        print("open preference window here")
        if let storyboard = NSStoryboard(name: NSStoryboard.Name(rawValue: "Main"), bundle: nil) {
            let controller = storyboard.instantiateControllerWithIdentifier("preferencesWindow")
 as NSViewController

            if let window = NSApplication.shared.mainWindow {
                window.contentViewController = controller // just swap
            }
        }
    }

但它在这一行抛出错误
如果let storyboard = NSStoryboard(名称:NSStoryboard.名称(原始值:“Main”),bundle:nil){
陈述
条件绑定的初始化程序必须为Optional类型,而不是“NSStoryboard”
当我点击首选项时,print语句会被记录下来,但我不知道如何以编程方式打开Windows。
我刚刚从对象库中拖动了窗口控制器,并为StoryBoard ID指定了preferencesWindow的值
由于上述错误,我还尝试了以下方法

@objc func preferencesWindow(_ sender: Any) {
        print("open preference window here")
        let storyboard = NSStoryboard(name: NSStoryboard.Name(rawValue: "Main"), bundle: nil)
        let controller = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "preferencesWindow")) as! NSViewController

        if let window = NSApplication.shared.mainWindow {
            window.contentViewController = controller // just swap
        }
    }

但它只记录&从不打开窗口。我该怎么办?

zphenhs4

zphenhs41#

当我在SO上发布问题时,我很快就找到了答案。这就是我的方法

@objc func preferencesWindow(_ sender: Any) {
        var myWindow: NSWindow? = nil
        let storyboard = NSStoryboard(name: NSStoryboard.Name(rawValue: "Main"),bundle: nil)
        let controller = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "preferencesWindow")) as! NSViewController
        myWindow = NSWindow(contentViewController: controller)
        NSApp.activate(ignoringOtherApps: true)
        myWindow?.makeKeyAndOrderFront(self)
        let vc = NSWindowController(window: myWindow)
        vc.showWindow(self)
    }
fzsnzjdm

fzsnzjdm2#

与其示例化视图控制器,使用现有的窗口控制器应该是更好的选择,因为有些设置可能会直接设置到故事板。NSApp.activate(ignoringOtherApps: true)showWindow都不是必须的,makeKeyAndOrderFront(_:)将激活窗口并直接标记为关键窗口。
告诉你,斯威夫特5:

let controller = NSStoryboard(name: "Main", bundle: nil).instantiateController(withIdentifier: "preferencesWindow") as! NSWindowController
controller.window!.makeKeyAndOrderFront(self)

相关问题