问题
I need implement Command + Enter, Command + O and Esc shotcuts for NSTokenField and solutonns like https://stackoverflow.com/a/18486965/1067147 not worked because -(void)noop:(SEL)sel isn't useful.
回答1:
My way is to create category for upper-in-hierarchy class NSView (also I try it for NSTextView but no luck):
// NSView+WideInterpreter.h
#import <Cocoa/Cocoa.h>
#define kNotificationTokenModifier @"kNotificationTokenModifier"
#define kNotificationTokenModifier_modifier @"kNotificationTokenModifier_modifier"
typedef enum{
BMTokenModifier_CommandEnter = 10,
BMTokenModifier_CommandO,
BMTokenModifier_Esc,
BMTokenModifier_nextKeyViewActivate
} BMTokenModifier;
@interface NSView (WideInterpreter)
@end
and
NSView+WideInterpreter.m
#import "NSView+WideInterpreter.h"
@implementation NSView (WideInterpreter)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
- (void)interpretKeyEvents:(id)keyEvents{
NSMutableArray *result = [[NSMutableArray alloc] init];
for (NSEvent *theEvent in keyEvents) {
NSUInteger clearFlags = ([theEvent modifierFlags] & NSDeviceIndependentModifierFlagsMask);
BOOL commandPressed = (clearFlags == NSCommandKeyMask);
switch ([theEvent keyCode]) {
case 31:{//Ctrl+O
if (commandPressed)
[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationTokenModifier
object:self
userInfo:@{kNotificationTokenModifier_modifier: @(BMTokenModifier_CommandO)}];
}break;
case 36:{//Enter
if (commandPressed)
[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationTokenModifier
object:self
userInfo:@{kNotificationTokenModifier_modifier: @(BMTokenModifier_CommandEnter)}];
else
[super insertNewlineIgnoringFieldEditor:self];
}break;
case 53://Esc
[[NSNotificationCenter defaultCenter] postNotificationName:kNotificationTokenModifier
object:self
userInfo:@{kNotificationTokenModifier_modifier: @(BMTokenModifier_Esc)}];
break;
default:// allow super to handle everything else
[result addObject:theEvent];
break;
}
}
[super interpretKeyEvents:result];
}
#pragma clang diagnostic pop
@end
For works with use:
[[NSNotificationCenter defaultCenter] addObserverForName:kNotificationTokenModifier
object:nil
queue:[NSOperationQueue currentQueue]
usingBlock:^(NSNotification *note) {
BMTokenModifier modifier = (BMTokenModifier)[[[note userInfo] objectForKey:kNotificationTokenModifier_modifier] integerValue];
switch (modifier) {
case BMTokenModifier_CommandEnter:
[self sendMessage];
break;
case BMTokenModifier_CommandO:
[self attachFiles];
break;
default:
break;
}
}];
来源:https://stackoverflow.com/questions/23897021/nstokenfield-catch-some-nsevents