检测 NSTextField 何时变为活动状态
Detecting when NSTextField becomes active
具体来说,我希望在 NSTextField
获得焦点时或当用户单击它并准备开始编辑时收到通知。
我已经尝试了 textDidBeginEditing:
方法,但这仅在用户实际开始键入时触发,而当文本字段成为第一响应者时我需要它。
我试过覆盖 -(BOOL)becomeFirstResponder
但只有当文本字段 first 成为第一响应者而不是之后的任何时间。
我尝试注册 NSControlDidBeginEditing
通知,但从未收到任何通知。
这可能吗?
实现 window 的委托方法 windowWillReturnFieldEditor:toObject:
。这告诉您字段编辑器正在切换到不同的对象。查看此对象是否为文本字段。
或者,继承 NSWindow 并覆盖 makeFirstResponder:
。调用 super
,查看哪个响应者正在成为第一响应者,以及对 super
的调用是否 return 为 YES,以及 return 对 [=12= 的调用的结果].
澄清一下 @matt
的回答让我走上了正确的道路;我想我应该明确说明如何做到这一点。
Aim
所以我想要一个 NSTextField
子类,它会知道它何时激活(即第一响应者),然后通知它的委托。
Problem
事实证明,OS X 文本编辑的背后是一个混乱的世界,您不能真正依赖 NSTextField
来完成所有工作。基本上当一个参与文本编辑的对象成为第一响应者时,一些东西(window,系统,NSApplication
)给它一个_NSKeyboardClipView
(我认为它叫做.. .) 作为子视图。反过来 _NSKeyboardClipView
有一个 NSTextView
作为子视图, 并且 NSTextView
成为第一响应者 .
Solution
• 子类化(或扩展)NSWindow 并覆盖 makeFirstResponder:
方法。
• 使用 NSNotificationCenter
发出通知,对象是传递给 makeFirstResponder:
方法的响应者对象。
• 在您的 NSTextField
子类中捕获通知。
• 这是可怕的一点:您需要检查 notification.object
是 a) NSView
的子类,以及 b) notification.object.superview.superview == self
(您必须将到 NSView
是因为对象的类型是 id
)。例如:
- (void)didBecomeFirstResponder:(NSNotification *)note
{
if ([note.object isKindOfClass:[NSView class]] && [[(NSView *)note.object superview] superview] == self) {
// You just became the first responder
}
}
这很糟糕 tacky/hacky 但它确实有效。
具体来说,我希望在 NSTextField
获得焦点时或当用户单击它并准备开始编辑时收到通知。
我已经尝试了 textDidBeginEditing:
方法,但这仅在用户实际开始键入时触发,而当文本字段成为第一响应者时我需要它。
我试过覆盖 -(BOOL)becomeFirstResponder
但只有当文本字段 first 成为第一响应者而不是之后的任何时间。
我尝试注册 NSControlDidBeginEditing
通知,但从未收到任何通知。
这可能吗?
实现 window 的委托方法 windowWillReturnFieldEditor:toObject:
。这告诉您字段编辑器正在切换到不同的对象。查看此对象是否为文本字段。
或者,继承 NSWindow 并覆盖 makeFirstResponder:
。调用 super
,查看哪个响应者正在成为第一响应者,以及对 super
的调用是否 return 为 YES,以及 return 对 [=12= 的调用的结果].
澄清一下 @matt
的回答让我走上了正确的道路;我想我应该明确说明如何做到这一点。
Aim
所以我想要一个 NSTextField
子类,它会知道它何时激活(即第一响应者),然后通知它的委托。
Problem
事实证明,OS X 文本编辑的背后是一个混乱的世界,您不能真正依赖 NSTextField
来完成所有工作。基本上当一个参与文本编辑的对象成为第一响应者时,一些东西(window,系统,NSApplication
)给它一个_NSKeyboardClipView
(我认为它叫做.. .) 作为子视图。反过来 _NSKeyboardClipView
有一个 NSTextView
作为子视图, 并且 NSTextView
成为第一响应者 .
Solution
• 子类化(或扩展)NSWindow 并覆盖 makeFirstResponder:
方法。
• 使用 NSNotificationCenter
发出通知,对象是传递给 makeFirstResponder:
方法的响应者对象。
• 在您的 NSTextField
子类中捕获通知。
• 这是可怕的一点:您需要检查 notification.object
是 a) NSView
的子类,以及 b) notification.object.superview.superview == self
(您必须将到 NSView
是因为对象的类型是 id
)。例如:
- (void)didBecomeFirstResponder:(NSNotification *)note
{
if ([note.object isKindOfClass:[NSView class]] && [[(NSView *)note.object superview] superview] == self) {
// You just became the first responder
}
}
这很糟糕 tacky/hacky 但它确实有效。