如何确定NSSearchField / NSTextField是否具有输入焦点?
答案 0 :(得分:29)
之前的回答是错误的,因为NSTextField
/ NSSearchField
本身不会成为第一个响应者并处理已编辑的文本。相反,他们使用窗口的字段编辑器,它是窗口上所有字段之间共享的NSTextView
(因为它们中只有一个可以一次聚焦)。
您需要查看第一个响应者是否为NSText
,如果是,则查询字段/文本字段是否为其委托。
NSResponder *firstResponder = [[NSApp keyWindow] firstResponder];
if ([firstResponder isKindOfClass:[NSText class]] && [(id)firstResponder delegate] == mySearchField) {
NSLog(@"Yup.");
}
答案 1 :(得分:7)
Greg Titus'答案可能有效,我认为以下是更好的方法:
BOOL isFirstResponder = mySearchField.currentEditor == mySearchField.window.firstResponder;
答案 2 :(得分:0)
AppKit使用“字段编辑器”(即NSTextView
)来处理NSTextField
(或NSSearchField
或NSSecureTextField
)中的实际编辑。当您的文本字段的窗口具有键盘焦点时,它会将字段编辑器作为子视图,而窗口的第一响应者是字段编辑器。
因此,通常,您可以检查文本字段是否具有字段编辑器:
if textField.currentEditor() != nil {
// textField has the keyboard focus
} else {
// textField does not have the keyboard focus
}
但是,当您将焦点移出文本字段时(通过按Tab键或单击另一个文本字段),该文本字段会发布NSControl.textDidEndEditingNotification
(Objective-C :NSControlTextDidEndEditingNotification
)。如果文本字段中有一个委托,并且该委托实现了control(_:controlTextDidEndEditing:)
协议的NSControlTextEditingDelegate
方法,则该通知也将被调用。
在传递此通知时(包括调用委托方法),文本字段仍将字段编辑器作为子视图,并且字段编辑器的委托仍设置为文本字段。因此,如果您不希望文本字段在通知处理程序(或委托方法)中仍然具有键盘焦点,那么测试字段编辑器将给出错误的答案。
(您可能会认为这是一个奇怪的测试,因为毕竟AppKit向您发送了一条通知,通知您文本字段不再是键盘焦点,所以为什么要问呢?但是您的通知处理程序可能会调用其他一些需要检查的方法,您不必传递一个标志,说“哦,顺便说一句,文本字段现在/现在不是键盘焦点”。)
好的,无论如何,在发送NSControl.textDidEndEditingNotification
之前,AppKit会更改文本字段窗口的第一响应者。因此,您可以检查文本字段是否具有字段编辑器,以及该字段编辑器是否是其窗口的第一响应者。在处理NSControl.textDidEndEditingNotification
时,此测试将报告该文本字段没有键盘焦点。
extension NSTextField {
public var hasKeyboardFocus: Bool {
guard
let editor = currentEditor(),
editor == window?.firstResponder
else { return false }
return true
}
}