Ran into the same problem. Had "hot key" which I'd like to switch off while editing some text fields. I found solution for myself. There's no need in override lots of NSTextField
base methods.
Firstly, I removed all the "key equivalents". I used to detect Enter key down with the + (void)addLocalMonitorForEventsMatchingMask:(NSEventMask)mask handler:(NSEvent *(^)(NSEvent *))block
class method of NSEvent
. You pass block as a parameter, where you can check for some conditions. The first parameter is the event mask. For your task it would be NSKeyDownMask
, look for other masks at the NSEvent Reference Page
The parameter block will perform each time the user pushes the button. You should check if it is right button pushed, and - generally - if the current window first responder isn't some editable control. For that purposes we need NSWindow
category class just not to implement this code each time we deal with NSKeyDownMask
ed local monitors.
NSWindow+Responders
class listing:
@interface NSWindow (Responders)
- (BOOL)isEditableFirstResponder;
@end
@implementation NSWindow (Responders)
- (BOOL)isEditableFirstResponder
{
if (!self.firstResponder)
return NO;
if ([self.firstResponder isKindOfClass:[NSTextField class]])
{
NSTextField *field=(NSTextField *)self.firstResponder;
return field.isEditable;
}
if ([self.firstResponder isKindOfClass:[NSButton class]])
return YES;
return NO;
}
@end
Don't know if there's another way to check if we are now editing some text field or combo box. So, there's at least the part you add the local monitor somewhere in your class (NSWindow, NSView, some controller etc.).
- (void)someMethod
{
id monitor=[NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask handler:(NSEvent *)^(NSEvent *theEvent){
if (theEvent.keyCode== && ![self.window.isEditableFirstResponder])
{
}
return theEvent;
}];
}
Local monitors is safe remedy about the Apple rules. It works only inside your application. For global key down events you may use addGlobalMonitor
but Apple may reject your app from the AppStore.
And don't forget to remove the monitor when there's no need in it.
- (void)viewControllerShutdownMethod
{
[NSEvent removeMonitor:monitor];
}
Good luck.