2015-06-09 17 views
6

Я пытаюсь создать приложение для OS X с помощью Swift и Cocoa. Я хочу, чтобы приложение отвечало на ключевые события, не сосредотачиваясь на/в текстовом поле. Я создал новый проект какао с раскадровкой в ​​Xcode, и изменил класс ViewController.swift к следующему:Swift NSViewController отвечает на событие mouseDown, но не событие keyDown

import Cocoa 

class ViewController: NSViewController { 

    override func mouseDown(theEvent: NSEvent) { 
     println("Mouse Clicked") 
    } 

    override func keyDown(theEvent: NSEvent) { 
     println("Key Pressed") 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 
    } 

    override var representedObject: AnyObject? { 
     didSet { 
     } 
    } 

} 

Когда я запускаю программу, я получаю вывод на консоль, когда я нажимаю на окне, но я не Когда я нажимаю клавиши, получаю какой-либо выход в консоль.

Так что мои вопросы: Почему моя программа реагирует на события мыши, но не ключевые события? Какие дополнительные шаги мне нужно сделать для ключевых событий для работы с событиями мыши?

Похоже, что контроллер моего представления находится в цепочке ответчиков, так как он перехватывает события мыши, так что это не проблема. Я нашел другие ответы здесь на SE, говоря, что мне нужно подклассифицировать NSView или NSWindow класс. Возможно ли получить ключевые события без этого?

Заранее спасибо.

EDIT: В дополнение к принятому ответу, Swift - Capture keydown from NSViewController - отличное, ясное решение.

+0

Не могли бы вы предоставить свой код для подкласса NSView? Мне нужно сделать то же самое, что я считаю. Я пытаюсь получить клавиши со стрелками при нажатии. – justColbs

+1

Лучший ответ на этот вопрос находится здесь: http://stackoverflow.com/questions/32446978/swift-capture-keydown-from-nsviewcontroller/32447474 Я публикую это, потому что ни один из приведенных примеров не помог мне, и я получил действительно простой ответ в вышеприведенном сообщении, даже в Xcode 8 и Swift 3. – jvarela

+0

@jvarela Это хорошая ссылка. Благодарю. Я обновлю свой вопрос, чтобы связать его. – Bernem

ответ

7

Отличие, которое вы наблюдаете, связано с тем, что Cocoa обрабатывает события мыши и события клавиатуры несколько иначе. На ранней стадии процесса диспетчеризации событий все события отправляются объекту NSWindow по системе. Для событий мыши NSWindow перенаправляет их на представление, на которое пользователь нажал; для событий клавиатуры, NSWindow пересылает их на первый ответчик текущего окна ключа.

Первоначальный первый ответчик NSWindow - это само окно. Когда пользователь нажимает на NSView, NSWindow будет попробует, чтобы сделать это первым ответчиком, отправив сообщение acceptsFirstResponder. Если он вернет YES, щелкнутый вид станет первым ответчиком.

«gotcha», однако, что acceptsFirstResponder возвращает NO по умолчанию. Как простой NSView не станет первым ответчиком, он не получит события клавиатуры. Таким образом, самым простым решением является подкласс вашего NSView, переопределить acceptsFirstResponder, чтобы вернуть YES.