当NSTextField成为焦点时设置selectedRange

时间:2019-02-21 19:55:05

标签: macos cocoa nstextfield appkit

我要重写becomeFirstResponder才能知道我的NSTextField何时专注。一旦聚焦,我试图将光标移到末尾。以下代码段无效:

@interface MyTextField : NSTextField
@end

@implementation MyTextField

- (BOOL)becomeFirstResponder
{
  if ([super becomeFirstResponder]) {
    self.currentEditor.selectedRange = NSMakeRange(self.stringValue.length, 0);
    return YES;
  }
  return NO;
}

@end

通过覆盖textView:didChangeSelection:,我发现选择已完成,但是随后被响应NSEventTypeLeftMouseDown事件而运行的一些内部代码覆盖。

日志如下:

location=0, length=25

location=25, length=0 // The desired selection.

location=0, length=0

location=5, length=0 // Where the user clicked.

2 个答案:

答案 0 :(得分:0)

覆盖mouseDown:子类中的NSTextField方法。

然后,在调用super之后设置selectedRange

- (void)mouseDown:(NSEvent *)event
{
  [super mouseDown:event];
  self.currentEditor.selectedRange = NSMakeRange(self.stringValue.length, 0);
}

NSTextField仅在其“字段编辑器”尚未聚焦时才调用其mouseDown:方法,因此用户在NSTextField获得聚焦之后仍可以更改选择。

这不是一个完美的解决方案,因为用户可能间接地将NSTextField聚焦(例如:使用Tab键)。不过,您始终可以在selectedRange mouseDown:中都设置becomeFirstResponder

答案 1 :(得分:0)

performSelector:withObject:afterDelay:内部使用becomeFirstResponder,以确保在处理selectedRange事件之后设置NSEventTypeLeftMouseDown

- (BOOL)becomeFirstResponder
{
  if ([super becomeFirstResponder]) {
    [self performSelector:@selector(textFieldDidFocus) withObject:nil afterDelay:0.0];
    return YES;
  }
  return NO;
}

- (void)textFieldDidFocus
{
  self.currentEditor.selectedRange = NSMakeRange(self.stringValue.length, 0);
}