Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
711 views
in Technique[技术] by (71.8m points)

macos - Detecting key press event in Swift

I'm trying to find a way to detect if a key (on a keyboard) has been pressed on Swift. Any ideas and suggestions will be greatly appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Since you updated your question and you wanted to know how to do this for a window, here's an answer. Subclass NSWindow and use this subclass instead.

Your custom class should look like this:

import Cocoa

class EditorWindow: NSWindow {
    override func keyDown(event: NSEvent) {
        super.keyDown(event)
        Swift.print("Caught a key down: (event.keyCode)!")
    }
}

If you've made your window in Interface Builder/XCode, click the window object and go to the Attribute Inspector (?+?+3). The Attribute Inspector will be in the sidebar on the right. Making sure your window is selected in Interface Builder, at the top of the Attribute Inspector in the Custom Class area put your new class in the class input.

Attribute Selector

In order to communicate the event from the this window class to my app I add a function to the window that accepts a callback function that I then store in an array of callback functions. I get access to this window through the AppDelegate which can get a weak reference to the current main window. Then in the above function I iterate overall the callbacks and call it with the NSEvent as the argument. I also first check to see if any command keys like the option keys are being pressed first through modifierFlags property on the event. It ends up looking like this:

import Cocoa

typealias Callback = (NSEvent) -> ()

class KeyCaptureWindow: NSWindow {

    var keyEventListeners = Array<Callback>()

    override func keyDown(event: NSEvent) {
        if event.modifierFlags.contains(NSEventModifierFlags.CommandKeyMask) {
            super.keyDown(event)
            return
        }
        for callback in keyEventListeners {
            callback(event)
        }
    }

    func addKeyEventCallback(callback: Callback) {
        keyEventListeners.append(callback)
    }


}

And then elsewhere in my code I have a line like so:

    let appDelegate = NSApplication.sharedApplication().delegate as! AppDelegate
    let mainWindow = appDelegate.getWindow()
    mainWindow.addKeyEventCallback(handleKeyEvent)

I added the getWindow method to my app delegate class. This method returns the NSWindow cast to KeyCaptureWindow. There may be a better way to do all this but this works for me. Another way to possibly do this is to use first responders and NSView, but that's not how I've been doing it.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...