Могу ли я выбрать определенный блок текста в UITextField?

У меня в приложении для iPhone есть UITextField. Я знаю, как заставить текстовое поле выделять весь его текст, но как можно изменить выделение? Скажем, я хотел выбрать последние 5 символов или конкретный диапазон символов, это возможно? если нет, могу ли я переместить линии, отмечающие начало и конец выделения, как если бы пользователь их перетаскивал?

6 ответов

Решение

С UITextField вы не можете. Но если вы видите заголовки, у вас есть _selectedRange и другие, которые могут быть использованы, если вы добавите в него некоторые категории;)


Обновление для iOS5 и выше:

Теперь UITextField и UITextView соответствуют протоколу UITextInput, так что это возможно:)

Выбор последних 5 символов перед кареткой будет выглядеть следующим образом:

// Get current selected range , this example assumes is an insertion point or empty selection
UITextRange *selectedRange = [textField selectedTextRange];

// Calculate the new position, - for left and + for right
UITextPosition *newPosition = [textField positionFromPosition:selectedRange.start offset:-5];

// Construct a new range using the object that adopts the UITextInput, our textfield
UITextRange *newRange = [textField textRangeFromPosition:newPosition toPosition:selectedRange.start];

// Set new range
[textField setSelectedTextRange:newRange];

Чтобы выбрать определенный диапазон символов, вы можете сделать что-то подобное в iOS 5+

int start = 2;
int end = 5;
UITextPosition *startPosition = [self positionFromPosition:self.beginningOfDocument offset:start];
UITextPosition *endPosition = [self positionFromPosition:self.beginningOfDocument offset:end];
UITextRange *selection = [self textRangeFromPosition:startPosition toPosition:endPosition];
self.selectedTextRange = selection;

поскольку UITextFields и другие элементы UIKit имеют свои собственные частные подклассы UITextPosition а также UITextRange Вы не можете создавать новые значения напрямую, но вы можете использовать текстовое поле, чтобы создать их для вас из ссылки на начало или конец текста и целочисленного смещения.

Вы также можете сделать обратное, чтобы получить целочисленные представления начальной и конечной точек текущего выбора:

int start = [self offsetFromPosition:self.beginningOfDocument toPosition:self.selectedTextRange.start];
int end = [self offsetFromPosition:self.beginningOfDocument toPosition:self.selectedTextRange.end];

Вот категория, которая добавляет методы для обработки выбора, используя NSRanges. https://gist.github.com/4463233

Чтобы выбрать имя файла без расширения файла, используйте это:

-(void) tableViewCellDidBeginEditing:(UITableViewTextFieldCell*) cell
{
    NSInteger fileNameLengthWithoutExt = [self.filename length] - [[self.filename pathExtension] length];
    UITextField* textField = cell.textField;
    UITextPosition* start = [textField beginningOfDocument];
    UITextPosition* end = [textField positionFromPosition:start offset: fileNameLengthWithoutExt - 1]; // the -1 is for the dot separting file name and extension
    UITextRange* range = [textField textRangeFromPosition:start toPosition:end];
    [textField setSelectedTextRange:range];
}

Они оба работают для меня:

[UITextField selectAll:self];

а также:

UITextField.selectedRange = NSMakeRange(0, 5);

но только если текстовое поле является первым респондентом. (Другими словами, только если клавиатура показывает.) Таким образом, вы должны предварять любой из методов выбора следующим:

[UITextField becomeFirstResponder];

если вы хотите, чтобы текст отображался выделенным.

Просто небольшое дополнение к принятому ответу. В iOS 5 следующая строка вылетает из моего приложения, когда длина текста UITextView равна 0 (нет текста):

[self textRangeFromPosition:startPosition toPosition:endPosition];

Небольшой обходной путь, чтобы добавить length == 0 проверить как:

if (textField.text && textField.text.length > 0) {
    // Get current selected range , this example assumes is an insertion point or empty selection
    UITextRange *selectedRange = [textField selectedTextRange];

    // Calculate the new position, - for left and + for right
    UITextPosition *newPosition = [textField positionFromPosition:selectedRange.start offset:-5];

    // Construct a new range using the object that adopts the UITextInput, our textfield
    UITextRange *newRange = [textField textRangeFromPosition:newPosition toPosition:selectedRange.start];

    // Set new range
    [textField setSelectedTextRange:newRange];
}

стриж

Выберите последние 5 символов:

if let newPosition = textField.positionFromPosition(textField.endOfDocument, inDirection: UITextLayoutDirection.Left, offset: 5) {

    textField.selectedTextRange = textField.textRangeFromPosition(newPosition, toPosition: textField.endOfDocument)
}

Выберите произвольный диапазон:

// Range: 3 to 7
let startPosition = textField.positionFromPosition(textField.beginningOfDocument, inDirection: UITextLayoutDirection.Right, offset: 3)
let endPosition = textField.positionFromPosition(textField.beginningOfDocument, inDirection: UITextLayoutDirection.Right, offset: 7)

if startPosition != nil && endPosition != nil {
    textField.selectedTextRange = textField.textRangeFromPosition(startPosition!, toPosition: endPosition!)
}

Мой полный ответ здесь.

Swift 5.0

вот как я выбираю имя файла Panda из Panda.txt

func textFieldDidBeginEditing(_ textField: UITextField) {
    // if textField.text is `Panda.txt`, offset will be 3
    let offset = String(textField.text!.split(separator: ".").last!).length
    let from = textField.position(from: textField.beginningOfDocument, offset: 0)
    let to = textField.position(from: textField.beginningOfDocument,
                                offset:textField.text!.length - (offset+1) )
    //now `Panda` will be selected
    textField.selectedTextRange = textField.textRange(from: from!, to: to!)
}

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