上下文菜单期间未调用“关键修饰符”监视器

时间:2018-09-23 16:17:53

标签: swift macos nsmenu nsmenuitem

关于:NSMenuDelegate methods not called for contextual menu一旦可见,我的视图委托就不会被调用。

newWindowMenuItem的标题,我想根据按键修饰符动态切换。

func menuWillOpen(_ menu: NSMenu) {
    guard newWindowMenuItem.title != "close" else {
        return
    }
    newWindowMenuItem.title = (appDelegate.shiftKeyDown) ? "Tab" : "Window"
    menu.update()
}

func menuDidClose(_ menu: NSMenu) {
    if menu == newWindowMenuItem.menu {
        newWindowMenuItem.title = "closed"
    }
}

func menu(_ menu: NSMenu, willHighlight item: NSMenuItem?) {
    if let currentEvent = NSApp.currentEvent, item == newWindowMenuItem {
        let flags = currentEvent.modifierFlags
        newWindowMenuItem.title = (flags.contains(.command)) ? "Tab" : "Window"
        menu.update()
        Swift.print("title \(newWindowMenuItem.title)")
    }
}

在viewDidLoad()中注册为

 NotificationCenter.default.addObserver(
    self,
    selector: #selector(WebViewController.shiftKeyDown(_:)),
    name: NSNotification.Name(rawValue: "shiftKeyDown"),
    object: nil)

我试图允许用户在按下修饰符时动态更改菜单项-主要是标题。由于在绘制菜单后会发生这种情况,因此使用menuWillOpen()似乎不可行,否则他们可能会在绘制菜单之前按下CTRL键以外的其他修饰符。

我当时正在考虑完全跳过该委托-因为我没有为我的需要阅读合适的方法来进行键修饰符更改,而是由一个键监视器来影响更改:

internal func shiftKeyDown(_ notification : Notification) {
    let shiftKeyDown : NSNumber = notification.object as! NSNumber
    Swift.print(String(format: "shift %@", shiftKeyDown.boolValue ? "v" : "^"))

    guard webView.menu != nil else {
        return
    }
    newWindowMenuItem.title = shiftKeyDown.boolValue ? "Tab" : "Window"
    newWindowMenuItem.menu?.update()
}

但这从来没有被调用过或者是关键事件,后菜单显示暗示我的方法是错误的吗?

2 个答案:

答案 0 :(得分:0)

您没有正确注册通知处理程序。方法

internal func shiftKeyDown(_ notification : Notification)

没有机会被调用,因为它没有被标记为@objc。应该写

@objc internal func shiftKeyDown(_ notification : Notification)

您可能确实在某个地方调用了另一种shiftKeyDown方法,或者您的注册码根本不起作用。 (或者您在某处有一个类似的命名方法,而在某处有错字。)

({NotificationCenter仍然只是Objective C NSNotificationCenter的奇特的Swift名称,而它又基于更老的CFNotificationCenter。Swift的整个#selector特性是建立在objc运行时之上,因此它仅适用于objc方法。)

答案 1 :(得分:0)

@Michael有正确的主意;我讨厌上下文菜单上的按键,这导致我在这里,但也很简单!在上下文菜单中构建项目/替代项

    item = NSMenuItem(title: "Window", action: #selector(appDelegate.newDocument(_:)), keyEquivalent: "")
    item.target = appDelegate
    subOpen.addItem(item)

    item = NSMenuItem(title: "Tab", action: #selector(appDelegate.newDocument(_:)), keyEquivalent: "")
    item.keyEquivalentModifierMask = .shift
    item.target = appDelegate
    item.isAlternate = true
    item.tag = 1
    subOpen.addItem(item)