Установите selectedRange, когда NSTextField становится сфокусированным

Я переопределяю 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.

Немного хакерский, но вы можете поставить код self.currentEditor.selectedRang... в очередь для запуска в следующем цикле событий.

James Bucanek 21.02.2019 23:48
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
1
83
2

Ответы 2

Переопределите метод mouseDown: в вашем подклассе NSTextField.

Затем установите selectedRangeпосле, вызывая super.

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

NSTextField вызывает свой метод mouseDown: только тогда, когда его «редактор поля» еще не сфокусирован, поэтому пользователь все еще может изменить выделение после того, как NSTextField получит фокус.

Это не идеальное решение, потому что пользователь мог сфокусировать NSTextField косвенно (например, с помощью клавиши Tab). Вы всегда можете установить selectedRange в обоих mouseDown:иbecomeFirstResponder.

Используйте 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);
}

Другие вопросы по теме