在无nib的Cocoa应用程序中,NSApplication菜单栏没有按预期响应

时间:2016-06-11 04:41:31

标签: swift cocoa

我有以下单个代码文件,其中我尝试使用尽可能少的代码创建具有基本功能的Cocoa应用程序,而不使用nib或Xcode。我从以下博客文章中获取了大部分信息,其中发布了等效的Objective-C代码:(http://www.cocoawithlove.com/2010/09/minimalist-cocoa-programming.html)。我所做的唯一重大改变是用于管理窗口的AppDelegate类,这通常是在Xcode项目中完成的。

import Cocoa

class AppDelegate: NSObject, NSApplicationDelegate {
    var window: NSWindow

    override init() {
        self.window = NSWindow()
        self.window.setFrame(NSRect(x: 0, y: 0, width: 1280, height: 720), display: true)
        self.window.collectionBehavior = .FullScreenPrimary
        self.window.styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask
        self.window.title = "Main Window"
    }

    func applicationDidFinishLaunching(notification: NSNotification) {
        window.makeKeyAndOrderFront(self)
    }

    func applicationShouldTerminateAfterLastWindowClosed(sender: NSApplication) -> Bool {
        return true
    }
}

autoreleasepool {
    NSApplication.sharedApplication()
    NSApp.setActivationPolicy(.Regular)

    let delegate = AppDelegate()
    NSApp.delegate = delegate

    let mainMenu = NSMenu()
    NSApp.mainMenu = mainMenu

    let applicationMenuItem = NSMenuItem()
    mainMenu.addItem(applicationMenuItem)

    let applicationMenu = NSMenu()

    let quitMenuItem = NSMenuItem()
    quitMenuItem.action = #selector(NSApp.terminate(_:))
    quitMenuItem.keyEquivalent = "q"
    quitMenuItem.title = "Quit Cocoa Window Test"
    applicationMenu.addItem(quitMenuItem)

    applicationMenuItem.submenu = applicationMenu

    NSApp.activateIgnoringOtherApps(true)
    NSApp.run()
}

我使用以下命令从终端成功编译:

swiftc -o bin/CocoaWindowTest -g -framework Cocoa ./src/main.swift

我的问题出现在菜单上。虽然⌘Q键盘快捷键按预期工作,但我创建的应用程序菜单无法打开,但我还没有找到原因。

2 个答案:

答案 0 :(得分:1)

您应该使用mainMenu.setSubmenu(applicationMenu, forItem:applicationMenuItem)来设置子菜单。具有子菜单的项目具有已分配的特殊操作submenuAction(_:),该操作负责实际显示子菜单。上述方法可以正确地指定该操作(并且最好自己设置)。

为了它的价值,在菜单完成之前我不会设置NSApp.mainMenu

答案 1 :(得分:1)

在调用NSApp.activateIgnoringOtherApps()后调用NSApp.run()解决了问题。总而言之,我的代码的主要部分现在读取如下内容:

autoreleasepool {
    NSApplication.sharedApplication()
    NSApp.setActivationPolicy(.Regular)

    let delegate = AppDelegate()
    NSApp.delegate = delegate

    // Menu setup here...

    NSApp.run()

    NSApp.activateIgnoringOtherApps(true)
}