Мне надоели все не ответы, чтобы сделать это другим способом, поэтому я опустил нос и нашел способ сделать эту работу.Это не использует событие keydown напрямую, но использует keydown в блоке.И поведение именно то, что я хотел.
Подкласс текстовое поле
.h
@interface LQRestrictedInputTextField : NSTextField
.m
В настройке стать первым респондентомлокальное событие
static id eventMonitor = nil;
- (BOOL)becomeFirstResponder {
BOOL okToChange = [super becomeFirstResponder];
if (okToChange) {
[self setKeyboardFocusRingNeedsDisplayInRect: [self bounds]];
if (!eventMonitor) {
eventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask handler:^(NSEvent *event) {
NSString *characters = [event characters];
unichar character = [characters characterAtIndex:0];
NSString *characterString=[NSString stringWithFormat:@"%c",character];
NSArray *validNonAlphaNumericArray = @[@" ",@"(",@")",@"[",@"]",@":",@";",@"\'",@"\"",@".",@"<",@">",@",",@"{",@"}",@"|",@"=",@"+",@"-",@"_",@"?",@"#",
@(NSDownArrowFunctionKey),@(NSUpArrowFunctionKey),@(NSLeftArrowFunctionKey),@(NSRightArrowFunctionKey)];
if([[NSCharacterSet alphanumericCharacterSet] characterIsMember:character] || character == NSCarriageReturnCharacter || character == NSTabCharacter || character == NSDeleteCharacter || [validNonAlphaNumericArray containsObject:characterString ] ) { //[NSCharacterSet alphanumericCharacterSet]
} else {
NSBeep();
event=nil;
}
return event;
} ];
}
}
NSLog(@"become first responder");
return okToChange;
}
удалить событие после завершения редактирования текстового поля
Также, если вы используете ARC, я заметил, что вам может потребоваться назначить строку textview для stringValue.Я nslog'd stringValue и значение было сохранено.Без nslog я должен был назначить строку объекта уведомления для stringValue, чтобы предотвратить его освобождение.
-(void) textDidEndEditing:(NSNotification *)notification {
[NSEvent removeMonitor:eventMonitor];
eventMonitor = nil;
NSTextView *textView=[notification object];
self.stringValue=textView.string;
}