I have a custom NSView subclass that needs to handle some keyboard events. In Objective-C, I might handle it like this:
-(void)keyDown:(NSEvent *)event
{
unichar ch = [[event charactersIgnoringModifiers] characterAtIndex:0];
if (ch == NSUpArrowFunctionKey && (event.modifierFlags & NSCommandKeyMask)) {
// Scroll to top
return;
}
else if (ch == NSDownArrowFunctionKey && (event.modifierFlags & NSCommandKeyMask)) {
// Scroll to bottom
return;
}
switch (ch) {
case NSRightArrowFunctionKey:
// Select the current row
return;
case ' ':
// Scroll down one page
return;
default:
break;
}
[super keyDown:event];
}
In Swift, however,characterAtIndex:
returns a unichar
, while NSUpArrowFunctionKey: Int
and " ": String
(or Character
). It's not clear to me how to convert a unichar to a String
or Character
.
I got this working, but it feels like an ugly workaround. Is there a better way?
func keyDown(theEvent: NSEvent) {
let char = Int(theEvent.charactersIgnoringModifiers.utf16[0]) // <----- This seems ugly
let hasCommand = (theEvent.modifierFlags & .CommandKeyMask).value != 0
switch char {
case NSUpArrowFunctionKey where hasCommand == true:
// Scroll to top
break
case NSDownArrowFunctionKey where hasCommand == true:
// Scroll to bottom
break
case NSRightArrowFunctionKey where hasCommand == true:
// Select the current row
break
case Int(" ".utf16[0]): // <---- Surely there's a better way of doing this?
// Scroll down one page
break
default:
super.keyDown(theEvent)
}
}
Let the oft-overlooked interpretKeyEvents()
do the messy bits for you. It knows about all sorts of keys, including arrow keys:
override func keyDown(event: NSEvent) {
interpretKeyEvents([event]) // calls insertText(_:), moveUp(_:), etc.
}
override func insertText(insertString: AnyObject) {
let str = insertString as! String
switch str {
case " ":
println("User hit the spacebar.")
default:
println("Unrecognized input: \(str)")
}
}
override func moveUp(sender: AnyObject?) {
println("Up arrow.")
}
override func moveLeft(sender: AnyObject?) {
println("Left arrow.")
}
override func deleteBackward(sender: AnyObject?) {
println("Delete.")
}
The NSResponder Class Reference section Responding to Action Messages lists these and other methods for handling keyboard events.