简体   繁体   中英

Programatically changing button text and actions when a modifier key is pressed

I would like to change the text of an NSButton when the ⌥ Option key is pressed - similar to the copy dialog when colliding files are detected on OS X which changes "Keep Both" to "Merge" when the option key is held.

In my case, I would like to change a button with text, say, "delete" to "quit" when I hold the option key. Additionally, its functionality should change in accordance with its title, much like the options in the Copy dialog.

Can this be done programatically in Swift?

You can subscribe using addLocalMonitorForEvents(matching:) and detect if option key pressed like this:

var optionKeyEventMonitor: Any? // property to store reference to the event monitor

// Add the event monitor
optionKeyEventMonitor = NSEvent.addLocalMonitorForEvents(matching: .flagsChanged) { event in
    if event.modifierFlags.contains(.option) {
        self.button.title = "copy"
        self.button.action = #selector(self.copyButtonClicked(_:))
    } else {
        self.button.title = "delete"
        self.button.action = #selector(self.deleteButtonClicked(_:))
    }  
    return event
}

@IBAction func copyButtonClicked(_ sender: Any) {
    Swift.print("Copy button was clicked!")
}

@IBAction func deleteButtonClicked(_ sender: Any) {
    Swift.print("Delete button was clicked!")
}

Remember to remove the event monitor when you are done:

deinit {
    if let eventMonitor = optionKeyEventMonitor {
        NSEvent.removeMonitor(eventMonitor)
    }
}

If you don't want a separate method called depending on the option key state, you can check modifierFlags when button is clicked instead:

@IBAction func buttonClicked(sender: NSButton) {
    if NSEvent.modifierFlags().contains(.option) {
        print("option pressed")
    } else {
        print("option not pressed")
    }
}

In Swift 3 code:

func optionKeyDown() -> Bool
{
    return NSEvent.modifierFlags().contains(NSEventModifierFlags.option)
}

if optionKeyDown()
{
    print ("do option code")
}
else
{
    print ("do normal code")
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM