Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I need to get arrow key presses, but keyDown won't call (Swift)

Tags:

swift

keydown

I am trying to build a Mac App which displays images and I want to move on to the next image when I press the right arrow key. I have looked all over stackoverflow and the internet, but just can't seem to get it.

What I tried... I tried to use keyDown(theEvent: NSEvent)but it does not call when I press any keys. I believe this is because it is not in a text field of some kind, but not sure.

What Happens... When i'm testing the program, I press a key (with keyDown function ready to println("Key Pressed")) and I get the OS X reject noise and no println to the console.

I have heard of some people subclassing NSView to override acceptsFirstResponder, but I am new to subclassing so any direction you could point me in would be great. Or if there is a way to do it w/o subclassing NSView that would be great!

Thanks in advance! Sorry for the noobness.

like image 411
justColbs Avatar asked Jul 31 '15 14:07

justColbs


1 Answers

Subclassing is less difficult than it seems.

Short tutorial:

General assumption: keystrokes are going to be received in the view of a NSViewController subclass and to be processed in the view controller class

  • Create a new Cocoa Class named MyView as a subclass of NSView
  • Replace the contents of the created class with

    import Cocoa
    
    let leftArrowKey = 123
    let rightArrowKey = 124
    
    protocol MyViewDelegate {
      func didPressLeftArrowKey()
      func didPressRightArrowKey()
    }
    
    class MyView: NSView {
    
       var delegate : MyViewDelegate?
    
       override func keyDown(event: NSEvent) {
         let character = Int(event.keyCode)
         switch character {
         case leftArrowKey, rightArrowKey:
           break
         default:
           super.keyDown(event)
         }
       }
    
       override func keyUp(event: NSEvent) {
         let character = Int(event.keyCode)
         switch character {
         case leftArrowKey:
           delegate?.didPressLeftArrowKey()
         case rightArrowKey:
           delegate?.didPressRightArrowKey()
         default:
           super.keyUp(event)
         }
       }
    
        override var acceptsFirstResponder : Bool {
          return true
        }
      } 
    
    • Change the class of the view of the ViewController in Interface Builder to MyView
    • In the ViewController class add the protocol MyViewDelegate- for example

      class ViewController: NSViewController, MyViewDelegate {
      
    • In viewDidLoad() add

      let view = self.view as! MyView
      view.delegate = self
      self.nextResponder = view
      
    • Implement the following delegate methods and add your code to switch the image(s)

      func didPressLeftArrowKey() {
        println("didPressLeftArrowKey")
        // process keystroke left arrow
      }
      
      func didPressRightArrowKey() {
        println("didPressRightArrowKey")
        // process keystroke right arrow
      }
      

The delegate methods are called when the appropriate arrow keys are released

like image 80
vadian Avatar answered Nov 10 '22 07:11

vadian