Я нашел хакерское обходное решение для достижения такого рода поведения. Я создал demo project, соответствующий класс TerminalLikeTextView. Это решение работает отлично, но мне все же хотелось бы иметь лучшее решение: менее хакерское и менее зависимое от внутренней механики NSTextView, поэтому, если кто-нибудь имеет такую просьбу, пожалуйста, поделитесь.
Основные шаги:
1) Установить mouseDownFlag Да, прежде чем мышь вниз и НЕТ после того, как:
@property (assign, nonatomic) BOOL mouseDownFlag;
- (void)mouseDown:(NSEvent *)theEvent {
self.mouseDownFlag = YES;
[super mouseDown:theEvent];
self.mouseDownFlag = NO;
}
2) Для того, чтобы предотвратить точку вставки от обновления возврата раньше от updateInsertionPointStateAndRestartTimer
метода:
- (void)updateInsertionPointStateAndRestartTimer:(BOOL)flag {
if (self.mouseDownFlag) {
return;
}
[super updateInsertionPointStateAndRestartTimer:flag];
}
3) Первые два шага заставят точку ввода не перемещаться с помощью мыши, однако selectionRange
по-прежнему будет изменен, поэтому мы n ПЕД следить за ним:
static const NSUInteger kCursorLocationSnapshotNotExists = NSUIntegerMax;
@property (assign, nonatomic) NSUInteger cursorLocationSnapshot;
#pragma mark - <NSTextViewDelegate>
- (NSRange)textView:(NSTextView *)textView willChangeSelectionFromCharacterRange:(NSRange)oldSelectedCharRange toCharacterRange:(NSRange)newSelectedCharRange {
if (self.mouseDownFlag && self.cursorLocationSnapshot == kCursorLocationSnapshotNotExists) {
self.cursorLocationSnapshot = oldSelectedCharRange.location;
}
return newSelectedCharRange;
}
4) Попытка печати с помощью клавиш восстанавливает местоположение, если необходимо:
- (void)keyDown:(NSEvent *)event {
NSString *characters = event.characters;
[self insertTextToCurrentPosition:characters];
}
- (void)insertTextToCurrentPosition:(NSString *)text {
if (self.cursorLocationSnapshot != kCursorLocationSnapshotNotExists) {
self.selectedRange = NSMakeRange(self.cursorLocationSnapshot, 0);
self.cursorLocationSnapshot = kCursorLocationSnapshotNotExists;
}
[self insertText:text replacementRange:NSMakeRange(self.selectedRange.location, 0)];
}
Будет ли редактируемые = НЕТ, выбор = YES будет достаточно? или вам нужно что-то другое? вы можете уточнить? – Remizorrr
Этого может быть достаточно с учетом 'insertText: replacementRange:' будет работать с 'editable = NO', но не добавляет никакого текста. –
@StanislavPankevich может быть настроен только для редактирования справа перед вставкой, а затем вернуться к НЕТ? – faviomob