我有NSTextField
我根据用户操作设置了可编辑状态。当用户点击窗口内文本字段之外的任何位置时,我想结束编辑。
看起来很简单,但我无法让它发挥作用。我实现了controlTextDidEndEditing
和textDidEndEditing
,但没有运气,特别是当我点击不接受第一响应者状态的用户界面元素时。
答案 0 :(得分:0)
您可以为NSView编写子类并编写以下方法,并将nib文件的NSWindow中的NSView类更改为该子类。
- (void)mouseDown:(NSEvent *)event
{
[text setEditable:NO];
NSLog(@"mouseDown");
}
答案 1 :(得分:0)
可能有点脏,但您可以在“文本字段外”区域创建一个大透明按钮。编辑开始时显示,编辑结束时隐藏。如果用户点击此按钮,则停止编辑(并隐藏按钮)。
当我需要快速解决方案时解决这个问题。
答案 2 :(得分:0)
每个NSEvent都通过NSWindow的sendEvent:
方法传递。
您可以创建一个自定义NSWindow并覆盖sendEvent:
方法。如果发生鼠标按下事件,请通过NSNotificationCenter广播该事件:
- (void)sendEvent:(NSEvent *)event {
[super sendEvent:event];
if (event.type == NSLeftMouseDown) {
[[NSNotificationCenter defaultCenter] postNotificationName:kCustomWindowMouseDown object:self userInfo:@{@"event": event}];
}
}
在引用NSTextField的ViewController中,观察此通知:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(customWindowMouseDown:)
name:kCustomWindowMouseDown
object:self.view.window];
如果鼠标按下事件的位置在文本字段之外,请结束编辑:
- (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];
}
}
}
}
答案 3 :(得分:0)
在您无法对包含视图的窗口进行子类化的情况下,我会改善vignesh kumar的答案。
对于所有处理mouseDown的子视图/控件,包括超级视图本身,请实现:
- (void)mouseDown:(NSEvent *)event
{
[[self window] makeFirstResponder:self];
[super mouseDown:event];
}
对于某些控件(例如按钮),您可以更改为
- (void)mouseDown:(NSEvent *)event
{
[[self window] makeFirstResponder:[self superview]];
[super mouseDown:event];
}
否则可能会出现聚焦环