-2

That's my code:

override func keyDown(theEvent: NSEvent) { super.keyDown(theEvent) switch theEvent.character { case NSLeftArrowFunctionKey: println(1) case NSRightArrowFunctionKey: println(2) case NSDownArrowFunctionKey: println(3) case NSUpArrowFunctionKey: println(4) default: break } } 

As you can see, I try to recognize if one of arrow buttons was pressed, but it never works. Even the function keyDown never seems to be called.

That's what is written in viewDidAppear, if this can help you to provide the answer:

override func viewDidAppear() { super.viewDidAppear() self.view.window?.styleMask = NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask var frame = self.view.window?.frame var newHeight = CGFloat(438) var newWidth = CGFloat(415) frame?.size = NSMakeSize(newWidth, newHeight) self.view.window?.setFrame(frame!, display: true) self.view.window?.backgroundColor = NSColor.darkGrayColor() } 

In viewDidLoad I just add some non-selectable and non-editable NSTextFields like that:

var x = CGFloat(0) var y = CGFloat(0) var tag = 1 for var i = 0; i < 4; i++ { for var j = 0; j < 4; j++ { var tile = NSTextField(frame: NSRect(x: x, y: y, width: 100, height: 100)) tile.enabled = false tile.stringValue = "" tile.font = NSFont(name: "Helvetica", size: 75) tile.backgroundColor = NSColor.lightGrayColor() tile.editable = false tile.selectable = false tile.drawsBackground = true tile.alignment = NSTextAlignment(rawValue: 2)! tile.tag = tag x += 105 ar.append(tile) self.view.addSubview(tile) tag++ } x = 0 y += 105 } 

I just have no idea why keyDown doesn't work, so I'll really appreciate any help.

EDIT:

The whole class code:

import Cocoa import AppKit import Foundation class _048Main: NSViewController { var ar : Array<NSTextField> = [] var left = 0 var dict : Dictionary<Int, NSColor> = [:] var pic2 = NSColor.redColor() var pic4 = NSColor.whiteColor() var pic8 = NSColor.orangeColor() var pic16 = NSColor.magentaColor() var pic32 = NSColor() var pic64 = NSColor() var pic128 = NSColor() var pic256 = NSColor() // Some colors will be added var pic512 = NSColor() var pic1024 = NSColor() var pic2048 = NSColor() override func viewDidLoad() { super.viewDidLoad() dict[2] = pic2 dict[4] = pic4 dict[8] = pic8 dict[16] = pic16 dict[32] = pic32 dict[64] = pic64 dict[128] = pic128 dict[256] = pic256 dict[512] = pic512 dict[1024] = pic1024 dict[2048] = pic2048 var x = CGFloat(0) var y = CGFloat(0) var tag = 1 for var i = 0; i < 4; i++ { for var j = 0; j < 4; j++ { var tile = NSTextField(frame: NSRect(x: x, y: y, width: 100, height: 100)) tile.enabled = false tile.stringValue = "" tile.font = NSFont(name: "Helvetica", size: 75) tile.backgroundColor = NSColor.lightGrayColor() tile.editable = false tile.selectable = false tile.drawsBackground = true tile.alignment = NSTextAlignment(rawValue: 2)! tile.tag = tag x += 105 ar.append(tile) self.view.addSubview(tile) tag++ } x = 0 y += 105 } left = 16 generateTile() generateTile() } func generateTile() { var r = Int(arc4random_uniform(UInt32(left))) var tmp = 0 for var i = 0; i < 16; i++ { if ar[i].stringValue == "" { if tmp == r { var t = Int(arc4random_uniform(10)) switch t { case 0...1: ar[i].stringValue = "2" ar[i].backgroundColor = pic2 default: ar[i].stringValue = "4" ar[i].backgroundColor = pic4 } left-- break } tmp++ } } } override func viewDidAppear() { super.viewDidAppear() self.view.window?.styleMask = NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask var frame = self.view.window?.frame var newHeight = CGFloat(438) var newWidth = CGFloat(415) frame?.size = NSMakeSize(newWidth, newHeight) self.view.window?.setFrame(frame!, display: true) self.view.window?.backgroundColor = NSColor.darkGrayColor() } override func keyDown(theEvent: NSEvent) { super.keyDown(theEvent) switch theEvent.character { case NSLeftArrowFunctionKey: println(1) case NSRightArrowFunctionKey: println(2) case NSDownArrowFunctionKey: println(3) case NSUpArrowFunctionKey: println(4) default: super.mouseDown(theEvent) } } } 
8
  • What is .character? And what about your other similar question? Commented Apr 16, 2015 at 19:26
  • @ericd You can even delete .character, because the whole function doesn't work. And in my other question I was asking about using keyDown while editing text field. And now it's not editable, but the function doesn't work Commented Apr 16, 2015 at 19:47
  • Can you post the whole class? Commented Apr 16, 2015 at 19:54
  • @NikitinRoman I asked because the answer that was provided over there was interesting, but you seemed to have ignored it and I was wondering why. Commented Apr 16, 2015 at 19:56
  • @ericd, oh, I just forgot about it. I've found an easier solution for user to navigate. I'll now read it carefully, but it still doesn't answer my new question Commented Apr 16, 2015 at 20:01

4 Answers 4

5

Try this code

override func viewDidLoad() { super.viewDidLoad() NSEvent.addLocalMonitorForEventsMatchingMask(NSEventMask.KeyDownMask, handler: myKeyDownEvent) } func myKeyDownEvent(event: NSEvent) -> NSEvent { print(event.keyCode) // Do stuff with keyCode. In my own projects I trap certain // keycodes. // If you want to block certain keycodes just change the return value // to an optional ->NSEvent? and return nil instead of event. return event } 
Sign up to request clarification or add additional context in comments.

2 Comments

@Mostafizur. I'm new to StackOverflow so don't quite understand how people edit other people's posts. Do you need certain permission and/or get credit for editing? You added the text "Try this code". If you think it's worth trying why didn't you +1 it?
In Swift 5 the local monitor call is now NSEvent.addLocalMonitorForEvents(matching: NSEvent.EventTypeMask.keyDown, handler: myKeyDownEvent)
2

You just need to use an invisible button. First add a square button to your window. assign the desired key for it. make your button 0 pixels wide and 0 pixels height. Add an IBAction to your button and the code to be executed when the user press the key.

Another option is to addLocalMonitorForEventsMatchingMask for more info check this link

https://stackoverflow.com/a/32447474/2303865

Comments

2

Does your app even build?

NSEvent instances don't have a character property, they have a characters property. Using character should result in a failed build and an error message from Xcode. What's more characters returns an optional String whereas your switch cases are of type Int - this type-mismatch should result in a build failure also.

In my experience, the simplest way of finding out if any of the arrow keys are pressed is to switch on the event's keyCode property.

import Foundation import Cocoa let kLeftArrowKeyCode: UInt16 = 123 let kRightArrowKeyCode: UInt16 = 124 let kDownArrowKeyCode: UInt16 = 125 let kUpArrowKeyCode: UInt16 = 126 class ViewController: NSViewController { override func keyDown(theEvent: NSEvent) { switch theEvent.keyCode { case kLeftArrowKeyCode: println(1) case kRightArrowKeyCode: println(2) case kDownArrowKeyCode: println(3) case kUpArrowKeyCode: println(4) default: break } } } 

You can still use the predefined constants if you like, but these represent Unicode codes, so you'll need to convert them to a strings first, before you switch on characters.

1 Comment

Read comments under the question. I have an extension for NSEvent. Also, that's not an answer, because the problem is - keyDown function is never called
1

Ignoring the extra stuff about converting characters and the like, if your keyDown() function isn't even being called, the most probable reason is that you didn't tell the OS that your view can accept key events (via overriding acceptsFirstResponder).

Do this in the view class:

override var acceptsFirstResponder: Bool { get { return true } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.