NSView не перехватывает события keyDown

Мне нужно перехватывать события mouseDown и keyDown в подклассе NSViewController, и, поскольку это невозможно (пожалуйста, поправьте меня, если я ошибаюсь), я оставил свой класс GameViewController пустым и поместил все его методы в новый класс GameView. В инспекторе идентификации GameViewController.xib я установил для своего класса значение GameView, а для владельца файла — GameViewController. В конце концов, мой метод mouseDown работает, а keyDown — нет. Я пробовал это:

- (BOOL) acceptsFirstResponder {
    return YES;
}

но это не помогло.

Пожалуйста, покажи мне, что делать.

UPD: На самом деле метод keyDown работает, но сначала мне нужно нажать где-нибудь на пустом месте моего окна и только потом все работает, как было задумано. И снова события mouseDown запускаются без проблем. Что я могу делать неправильно?


person new_user    schedule 15.02.2015    source источник


Ответы (1)


Ваше представление принимает первого ответчика, когда его предлагают, но ничто не пытается сделать его первым ответившим, пока вы не нажмете.

Установите окно initialFirstResponder за некоторое время до его отображения. Если вы используете NIB, его можно установить там. Или можно сделать это программно.

После того, как окно показано, вы можете вызвать [window makeFirstResponder:view], чтобы сделать представление первым ответчиком своего окна.

person Ken Thomases    schedule 16.02.2015
comment
Подскажите, пожалуйста, куда именно этот вызов прописать, файлов для NSWindow у меня нет. Я попытался поместить [self.view.window makeFirstResponder: gameView] в viewDidLoad gameViewController, однако это тоже не работает. - person new_user; 16.02.2015
comment
Если представление создается отдельно от окна, что похоже на случай, поскольку оно загружается контроллером представления, вы не можете сделать его первым ответчиком, пока представление не будет добавлено в окно. Когда вы добавляете представление контроллера представления в окно и как? Вам нужно будет установить либо initialFirstResponder, либо вызвать -makeFirstResponder: после того, как представление будет добавлено в окно. - person Ken Thomases; 16.02.2015
comment
Я использую объект NSTabView для переключения своих представлений (поэтому мне нужен подкласс NSViewController), и он помещается в MainMenu.xib. Не означает ли это, что мои взгляды каким-то образом прилипли к окну? - person new_user; 17.02.2015
comment
Ну, с таким количеством абстракции и автоматизации может быть трудно понять, когда представление было добавлено в окно. Вы можете использовать собственный класс представления и переопределить -viewDidMoveToWindow. Вы можете реализовать делегат представления вкладок и реализовать -tabView:didSelectTabViewItem:. Если вы программно настраиваете выбранную вкладку вкладки, вы можете поместить вызов -makeFirstResponder: сразу после переключения на вкладку вашего игрового вида. - person Ken Thomases; 17.02.2015
comment
Я достиг некоторого прогресса, но с другим подходом. Помимо окна с пользовательским видом, у меня есть gameView и menuView в MainMenu.xib. Когда я нажимаю кнопку, я вызываю [[self.window.contentView animator] replaceSubview:self with:(NSView *)gameView]; и [self.window makeFirstResponder: (NSView *)gameView];, аналогично в обратном направлении. И это работает! Да, здесь я могу использовать свою клавиатуру без проблем. К сожалению, когда я снова переключаюсь на menuView и во второй раз захожу в gameView, клавиатура снова ломается. В чем мистификация такого изменения взглядов? - person new_user; 19.02.2015
comment
На самом деле мне не нужен метод -makeFirstResponder: , он работает и без него. - person new_user; 19.02.2015
comment
Извините, это была только моя вина. Я добавил [self.window makeFirstResponder: self]; к `-viewDidMoveToWindow', и теперь он работает нормально. Спасибо за вашу помощь! - person new_user; 19.02.2015