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.
-
1What did you try yourself ? – Steven Beaupré Jan 26 '15 at 21:29
-
4This is not a duplicate. Objective-C answers are not duplicates for Swift questions. – Bjorn Jan 26 '15 at 22:50
-
In what context did you want to detect a key press? On a window? An input? – Bjorn Jan 26 '15 at 22:53
-
Hi Bjorn, just in a window. I wanted to add an if statement, such as 'if the key 'A' was pressed, do something' etc. – andertonslase Jan 27 '15 at 01:08
-
Ok, just for anyone else interested I gave the exact example for how to do this for a window below. – Bjorn Jan 27 '15 at 15:41
-
any way in iOS? – Ramcharan Reddy Apr 23 '20 at 05:02
2 Answers
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.
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.

- 69,215
- 39
- 136
- 164
-
If there are multiple keyboards connected to the computer, is it possible to identift which keyboard the even came from? – OrangePot Mar 28 '17 at 19:59
-
2Recent versions of Swift have modified the function. It's now keyDown(with event: NSEvent). Thanks for the answer, very informative! – Nick K9 Feb 01 '18 at 20:33
You have to override the keyDown
-method.
var direction:String = ""
override func keyDown(theEvent: NSEvent!) // A key is pressed
{
if theEvent.keyCode == 123
{
direction = "left" //get the pressed key
}
else if theEvent.keyCode == 124
{
direction = "right" //get the pressed key
}
println("Key with number: \(theEvent.keyCode) was pressed")
}