Every NSEvent is pass through NSWindow's sendEvent:
method.
You can create a custom NSWindow and override the sendEvent:
method. If there is a mouse down event, broadcast it by the NSNotificationCenter:
- (void)sendEvent:(NSEvent *)event {
[super sendEvent:event];
if (event.type == NSLeftMouseDown) {
[[NSNotificationCenter defaultCenter] postNotificationName:kCustomWindowMouseDown object:self userInfo:@{@"event": event}];
}
}
In the ViewController which reference the NSTextField, observer this notification:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(customWindowMouseDown:)
name:kCustomWindowMouseDown
object:self.view.window];
End the editing if the mouse down event's location is outside of the text field:
- (void)customWindowMouseDown:(id)sender {
NSNotification *notification = (NSNotification *) sender;
NSEvent *event = notification.userInfo[@"event"];
NSPoint locationInWindow = event.locationInWindow;
if ([self.view.window.firstResponder isKindOfClass:NSTextView.class]) {
NSTextView *firstResponder = (NSTextView *) self.view.window.firstResponder;
//we only care about the text field referenced by current ViewController
if (firstResponder.delegate == (id <NSTextViewDelegate>) self.textField) {
NSRect rect = [self.textField convertRect:self.textField.bounds toView:nil];
//end editing if click out side
if (!NSPointInRect(locationInWindow, rect)) {
[self.view.window makeFirstResponder:nil];
}
}
}
}