У меня есть UITextField
, который я форсирую форматирование, изменяя текст внутри обработчика уведомлений об изменении. Это отлично работает (как только я решил проблемы с реентерацией), но оставил мне еще одну неприятную проблему.
Если пользователь перемещает курсор в другое место, отличное от конца строки, мое изменение форматирования перемещает его в конец строки. Это означает, что пользователи не могут вставлять более одного символа за раз в середину текстового поля.
Есть ли способ запомнить, а затем reset позицию курсора в UITextField
?
Управление позицией курсора в UITextField
Ответ 1
Управление позицией курсора в UITextField сложнее, потому что столько абстракций связано с полями ввода и вычислением позиций. Однако это, безусловно, возможно. Вы можете использовать функцию-член setSelectedTextRange
:
[input setSelectedTextRange:[input textRangeFromPosition:start toPosition:end]];
Здесь функция, которая принимает диапазон и выбирает тексты в этом диапазоне. Если вы просто хотите поместить курсор в определенный индекс, просто используйте диапазон с длиной 0:
+ (void)selectTextForInput:(UITextField *)input atRange:(NSRange)range {
UITextPosition *start = [input positionFromPosition:[input beginningOfDocument]
offset:range.location];
UITextPosition *end = [input positionFromPosition:start
offset:range.length];
[input setSelectedTextRange:[input textRangeFromPosition:start toPosition:end]];
}
Например, чтобы поместить курсор в idx
в UITextField input
:
[Helpers selectTextForInput:input
atRange:NSMakeRange(idx, 0)];
Ответ 2
Наконец-то я нашел решение этой проблемы! Вы можете поместить текст, который вам нужно вставить в системный картон, а затем вставить его в текущую позицию курсора:
[myTextField paste:self]
Я нашел решение в этом человеческом блоге:
http://dev.ragfield.com/2009/09/insert-text-at-current-cursor-location.html
Функциональность пасты зависит от ОС V3.0, но я ее протестировал, и она отлично работает для меня с пользовательской клавиатурой.
Если вы пойдете на это решение, вы должны, вероятно, сохранить содержимое существующего буфера обмена и немедленно восстановить его.
Ответ 3
Полезно позиционировать по индексу (Swift 3)
private func setCursorPosition(input: UITextField, position: Int) {
let position = input.position(from: input.beginningOfDocument, offset: position)!
input.selectedTextRange = input.textRange(from: position, to: position)
}
Ответ 4
Здесь Swift версия @Chris R. - обновлена для Swift3
private func selectTextForInput(input: UITextField, range: NSRange) {
let start: UITextPosition = input.position(from: input.beginningOfDocument, offset: range.location)!
let end: UITextPosition = input.position(from: start, offset: range.length)!
input.selectedTextRange = input.textRange(from: start, to: end)
}
Ответ 5
Я не думаю, что есть способ разместить курсор в определенном месте в вашем UITextField
(если только вы не очень сложны и не имитировали событие касания). Вместо этого я обработаю форматирование, когда пользователь закончит редактирование своего текста (в textFieldShouldEndEditing:
), и если их запись неверна, не разрешайте текстовому полю завершить редактирование.
Ответ 6
Не стесняйтесь использовать эту категорию UITextField
для получения и установки положения курсора:
@interface UITextField (CursorPosition)
@property (nonatomic) NSInteger cursorPosition;
@end
-
@implementation UITextField (CursorPosition)
- (NSInteger)cursorPosition
{
UITextRange *selectedRange = self.selectedTextRange;
UITextPosition *textPosition = selectedRange.start;
return [self offsetFromPosition:self.beginningOfDocument toPosition:textPosition];
}
- (void)setCursorPosition:(NSInteger)position
{
UITextPosition *textPosition = [self positionFromPosition:self.beginningOfDocument offset:position];
[self setSelectedTextRange:[self textRangeFromPosition:textPosition toPosition:textPosition]];
}
@end
Ответ 7
Вот фрагмент, который отлично подходит для этой проблемы:
- (void)textFieldDidBeginEditing:(UITextField *)textField{
UITextPosition *positionBeginning = [textField beginningOfDocument];
UITextRange *textRange =[textField textRangeFromPosition:positionBeginning
toPosition:positionBeginning];
[textField setSelectedTextRange:textRange];
}