当用户点击NSTextField
时,有人会建议选择NSTextField
的所有文字吗?
我确实找到了对mouseDown
进行子类化的建议,然后使用firstResponder
或{{1}},但现在已超出我的技能范围了。所以我希望有一个更简单的解决方案,或者有人可能会详细说明所需的步骤。
答案 0 :(得分:23)
没有更简单的解决方案,您需要将NSTextField
子类化为您想要的。如果要在Cocoa中执行任何有用的操作,您将需要学习如何处理子类。
文本字段对于子类来说可能相对复杂,因为NSTextField
使用称为“字段编辑器”的单独NSTextView
对象来处理实际编辑。此文本视图由NSWindow
的{{1}}对象返回,并重新用于页面上的所有文本字段。
与任何NSTextField
子类一样,NSResponder
会对方法NSTextField
和-acceptsFirstResponder
做出响应。当窗口想要将焦点放在特定控件或视图上时,会调用它们。如果从这两种方法返回-becomeFirstResponder
,那么您的控件/视图将具有第一响应者状态,这意味着它是活动控件。但是,如上所述,NSTextField实际上在单击时为字段编辑器提供了第一个响应者状态,因此您需要在YES
子类中执行类似的操作:
NSTextField
这首先调用超类的@implementation MCTextField
- (BOOL)becomeFirstResponder
{
BOOL result = [super becomeFirstResponder];
if(result)
[self performSelector:@selector(selectText:) withObject:self afterDelay:0];
return result;
}
@end
实现,它将完成管理字段编辑器的艰苦工作。然后调用-becomeFirstResponder
选择字段中的所有文本,但是在延迟0秒之后它会这样做,这将延迟到下一次运行事件循环。这意味着在完全配置字段编辑器后将进行选择。
答案 1 :(得分:5)
@Rob的答案可能在某一点上起作用,但正如@Daniel指出的那样,它不再起作用了。看起来Cocoa想要跟踪鼠标并拖出一个选择以响应点击,并且尝试选择响应becomeFirstResponder
的文本并不能很好地发挥作用。
需要拦截鼠标事件,以防止跟踪。或多或少通过反复试验,我找到了一个似乎适用于OS X 10.10的解决方案:
@interface MyAutoselectTextField : NSTextField
@end
@implementation MyAutoselectTextField
- (void)mouseDown:(NSEvent *)theEvent
{
[[self currentEditor] selectAll:nil];
}
@end
据我所知,当mouseDown:
被调用时,字段编辑器已经设置好,可能是becomeFirstResponder
的副作用。调用selectAll:
然后选择字段编辑器的内容。在selectText:
上调用self
代替效果不佳,可能是因为设置了字段编辑器。请注意,此处覆盖mouseDown:
不调用super
; super
会运行跟踪循环,拖出选择,我们不想要这种行为。请注意,一旦文本字段成为第一响应者,此mouseDown:
覆盖不会影响选择,因为此时正在调用字段编辑器mouseDown:
。
我不知道这个OS X版本的范围是多少;如果你关心,你需要测试它。不幸的是,使用NSTextField
总是有点脆弱,因为字段编辑器的工作方式非常奇怪,因此依赖于super
中的实现细节。
答案 2 :(得分:2)
Swift的一些更新:
import Cocoa
class TextFieldSubclass: NSTextField {
override func mouseDown(theEvent: NSEvent) {
super.mouseDown(theEvent)
if let textEditor = currentEditor() {
textEditor.selectedRange = NSMakeRange(location, length)
}
}
}
或者是为了精确选择:
import Cocoa
class TextFieldSubclass: NSTextField {
override func becomeFirstResponder() -> Bool {
let source = CGEventSourceCreate(CGEventSourceStateID.HIDSystemState)
let tapLocation = CGEventTapLocation.CGHIDEventTap
let cmdA = CGEventCreateKeyboardEvent(source, 0x00, true)
CGEventSetFlags(cmdA, CGEventFlags.MaskCommand)
CGEventPost(tapLocation, cmdA)
return true
}
}
Swift版本,适用于我:
{{1}}
答案 3 :(得分:0)
我知道这是一个古老的问题,但这是为那些可能迷失于此的人提供的更新。
重写NSTextField并连接到beginFirstResponder()中。您不必担心管理代表或点击。棘手的部分是首先要为重点文本字段找到字段编辑器,然后再要求它选择所有文本。
Objective-C
// in AutoselectOnFocusTextField.h
@interface AutoselectOnFocusTextField : NSTextField
@end
// in AutoselectOnFocusTextField.m
@implementation AutoselectOnFocusTextField
- (BOOL)becomeFirstResponder {
if (![super becomeFirstResponder]) {
return NO;
}
NSText* fieldEditor = [self currentEditor];
if (fieldEditor != nil) {
[fieldEditor performSelector:@selector(selectAll:) withObject:self afterDelay:0.0];
}
return YES;
}
@end
快速
class AutoselectOnFocusTextField: NSTextField {
override func becomeFirstResponder() -> Bool {
guard super.becomeFirstResponder() else {
return false
}
if let editor = self.currentEditor() {
editor.perform(#selector(selectAll(_:)), with: self, afterDelay: 0)
}
return true
}
}