【问题标题】:Detecting when NSTextField becomes active检测 NSTextField 何时变为活动状态
【发布时间】:2016-04-22 19:24:29
【问题描述】:

具体来说,我希望在NSTextField 获得焦点或用户单击它并即将开始编辑时收到通知。

我已经尝试过textDidBeginEditing: 方法,但这仅在用户实际开始输入时才会触发,并且当文本字段成为第一响应者时我需要它。

我已尝试覆盖 -(BOOL)becomeFirstResponder,但仅在文本字段 first 成为第一响应者时才调用它,之后不再调用。

我尝试注册NSControlDidBeginEditing 通知,但从未收到任何通知。

这可能吗?

【问题讨论】:

  • 在我的测试应用中,becomeFirstResponder 每次都会被调用。

标签: objective-c macos cocoa nstextfield


【解决方案1】:

实现窗口的委托方法windowWillReturnFieldEditor:toObject:。这告诉您字段编辑器正在切换到不同的对象。看看这个对象是否是文本字段。

或者,继承 NSWindow 并覆盖 makeFirstResponder:。调用super,看看哪个响应者变成了第一响应者,对super的调用是否返回YES,并将调用结果返回给super

【讨论】:

  • 第一个选项并没有真正起作用,因为当您成为第一响应者时,您会被对委托方法的调用所淹没,这些调用并不总是与它相关联。第二种选择是赚钱的人。谢谢。
【解决方案2】:

要明确@matt 的回答让我走上了正确的道路;我想我应该澄清一下你是如何做到这一点的。

目标

所以我想要一个NSTextField 子类,它会知道它何时变为活动状态(即第一响应者),然后通知它的委托。

问题

事实证明,OS X 文本编辑的底层是一个混乱的世界,您不能真正依赖 NSTextField 来完成这一切。基本上,当涉及文本编辑的对象成为第一响应者时,某些东西(窗口、系统、NSApplication)会给它一个_NSKeyboardClipView(我认为它被称为......)作为子视图。反过来,_NSKeyboardClipView 有一个 NSTextView 作为子视图,成为第一响应者的是 NSTextView

解决方案

• 继承(或扩展)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
    }
}

这很可怕而且俗气/骇人听闻,但确实有效。

【讨论】:

  • 在我的测试应用程序中,makeFirstResponder 也使用文本字段调用。 didBecomeFirstResponder 中的测试只是 note.object = self
  • @Willeke 是的,它确实调用了它,但只是第一次。
  • 奇怪,像becomeFirstRespondermakeFirstResponder每次都被调用。
  • 很晚的后续行动:在 Big Sur beta 2 上对此进行了测试:每次文本字段获得焦点时都会调用 becomeFirstResponder。然后它将firstResponder 辞职给字段编辑器。此外,每次字段失去焦点时都会调用textDidEndEditing,即使没有输入文本也是如此。当字段编辑器获得焦点时,这可能比探索视图层次结构更容易且不那么脆弱
猜你喜欢
  • 2012-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多