Я работаю над приложением для ввода текста для Mac OSX, которое должно иметь нажатые клавиши, даже если приложение не в фокусе.
Есть ли способ, чтобы система нажала клавиши в приложении, возможно, через NSDistributedNotificationCenter? Я глупо искал себя и не смог найти ответ...
EDIT: Пример кода ниже.
Спасибо @NSGod за то, что указали мне в правильном направлении - в итоге я добавил глобальный монитор событий, используя метод addGlobalMonitorForEventsMatchingMask: обработчик:, который прекрасно работает. Для полноты моя реализация выглядит так:
// register for keys throughout the device...
[NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask
handler:^(NSEvent *event){
NSString *chars = [[event characters] lowercaseString];
unichar character = [chars characterAtIndex:0];
NSLog(@"keydown globally! Which key? This key: %c", character);
}];
Для меня сложная часть использовала блоки, поэтому я дам небольшое описание, если это кому-то поможет:
О том, что следует отметить вышеприведенный код, является то, что все один метод вызывает на NSEvent. Блок предоставляется как аргумент, напрямую -. Вы могли бы подумать, что это похоже на встроенный метод делегата. Просто потому, что это заняло некоторое время, чтобы утонуть для меня, я буду работать через это шаг за шагом здесь:
[NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask
Этот первый бит не проблема. Вы вызываете метод класса на NSEvent и сообщаете ему, какое событие вы хотите контролировать, в данном случае NSKeyDownMask. A список масок для поддерживаемых типов событий можно найти здесь.
Теперь мы перейдем к сложной части: обработчик, ожидающий блок:
handler:^(NSEvent *event){
Мне потребовалось несколько компиляционных ошибок, чтобы получить это право, но (спасибо Apple) они были очень конструктивными сообщениями об ошибках. Первое, что нужно заметить, это карата. Это сигнализирует о начале блока. После этого в круглых скобках
NSEvent *event
Что объявляет переменную, которую вы будете использовать в блоке для захвата события. Вы могли бы назвать это
NSEvent *someCustomNameForAnEvent
не имеет значения, вы просто будете использовать это имя внутри блока. Тогда, что почти все есть. Не забудьте закрыть фигурные скобки и скобку, чтобы завершить вызов метода:
}];
И все готово! Это действительно "однострочный". Неважно, где вы выполняете этот вызов в своем приложении - я делаю это в методе appDelegate applicationDidFinishLaunching. Затем внутри блока вы можете вызывать другие методы из вашего приложения.