检测 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 但它确实有效。