Мне нужно получить нажатия клавиш со стрелками, но keyDown не будет вызывать (Swift)

Я пытаюсь создать приложение для Mac, которое отображает изображения, и я хочу перейти к следующему изображению, когда нажимаю клавишу со стрелкой вправо. Я просмотрел весь stackoverflow и Интернет, но просто не могу понять.

Что я пробовал... Я пытался использовать keyDown(theEvent: NSEvent), но он не вызывается, когда я нажимаю какие-либо клавиши. Я считаю, что это потому, что это не какое-то текстовое поле, но не уверен.

Что происходит... Когда я тестирую программу, я нажимаю клавишу (с функцией keyDown, готовой к println("Key Pressed")), и я получаю шум отклонения OS X и отсутствие вывода на консоль.

Я слышал о некоторых людях, создающих подклассы NSView для переопределения acceptsFirstResponder, но я новичок в создании подклассов, поэтому любое направление, в котором вы могли бы указать мне, было бы здорово. Или, если есть способ сделать это без подкласса NSView, это было бы здорово!

Заранее спасибо! Извините за нубство.


person justColbs    schedule 31.07.2015    source источник
comment
Где вы хотите зафиксировать событие Key Down? NSWindow, NSTableView, NSButton? Кроме того, пожалуйста, напишите, что вы пробовали.   -  person Code Different    schedule 31.07.2015
comment
@ZoffDino Я удалил то, что пробовал ранее. Я считаю, что хочу захватить событие в NSView, но я не уверен в этом.   -  person justColbs    schedule 31.07.2015


Ответы (1)


Подклассы менее сложны, чем кажется.

Краткое руководство:

Общее предположение: нажатия клавиш будут приниматься в представлении подкласса NSViewController и обрабатываться в классе контроллера представления.

  • Создайте новый класс какао с именем MyView в качестве подкласса NSView
  • Замените содержимое созданного класса на

    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
    • В классе ViewController добавьте протокол MyViewDelegate- например

      class ViewController: NSViewController, MyViewDelegate {
      
    • В viewDidLoad() добавить

      let view = self.view as! MyView
      view.delegate = self
      self.nextResponder = view
      
    • Реализуйте следующие методы делегата и добавьте свой код для переключения изображений.

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

Методы делегата вызываются при отпускании соответствующих клавиш со стрелками.

person vadian    schedule 31.07.2015
comment
Хорошо, кажется, я понимаю, как это работает. Итак, методы делегата входят в мой класс ViewController. Итак, как же меняются эти две строки (которые будут в «applicationDidFinishLaunching», когда я помещаю их в класс, у которого уже есть представление? - person justColbs; 31.07.2015
comment
протокол должен быть добавлен в класс, который обрабатывает нажатия клавиш и строку set delegate для контроллера представления. Если представление принадлежит контроллеру представления, то класс этого представления должен быть изменен на MyView. Затем вы должны сослаться на представление следующим образом: let view = self.view as! MyView - person vadian; 31.07.2015
comment
Я пробовал это и несколько других вещей, все еще не работает. Я ценю вашу помощь. У вас случайно нет рабочей версии этого кода, реализованной в контроллере представления? - person justColbs; 31.07.2015
comment
Я отредактировал сообщение, чтобы использовать подкласс NSViewController. Рассмотрим добавленную переменную acceptsFirstResponder в подклассе NSView. - person vadian; 31.07.2015
comment
Это будет победителем! Это сработало. Большое спасибо, сэр! - person justColbs; 31.07.2015