UITextView selectВсе метод не работает как ожидалось
Я создаю приложение iOS 8 с Xcode 6.0.1 для своего iPhone 5 (на нем есть iOS 8.0.2). Я хочу сделать так, чтобы, когда пользователь нажимает на мой UITextView
, весь текст выбирается, поэтому он может легко начать вводить и стирать то, что было там (но я не хочу, чтобы текст автоматически стирался, потому что пользователь может хотите сохранить его или добавить к нему). Для этого у меня есть следующий код:
- (void)textViewDidBeginEditing:(UITextView *)textView {
if ([textView hasText]) {
NSLog(@"selectedRange before: %d", textView.selectedRange.length);
[textView selectAll:self];
NSLog(@"selectedRange after: %d", textView.selectedRange.length);
}
}
Когда этот метод вызывается, вывод консоли - это то, что я ожидаю (т.е. длина selectedRange
совпадает с количеством символов в тексте textView
). Тем не менее, ничего не отображается, как выбрано в UITextView
, и оно не действует (т.е. Всплывающее меню выбора).
Я видел несколько вопросов, подобных этому в Интернете, но ни один из предоставленных решений не работал у меня (и некоторые из них записывали его как ошибку, не предоставляя никакого решения). Изменение идентификатора отправителя на что-то, отличное от self
(например, nil
), не помогло, и также не помогло вызвать [textView select:self]
, как предложил один человек. Я также пробовал этот код:
- (void)textViewDidBeginEditing:(UITextView *)textView {
if ([textView hasText]) {
UITextRange *range = [textView textRangeFromPosition:textView.beginningOfDocument toPosition:textView.endOfDocument];
[textView setSelectedTextRange:range];
}
}
Но это имеет ту же проблему.
Любые предложения?
Ответы
Ответ 1
Лучшим решением, которое я нашел для этой проблемы до сих пор, является создание пользовательского UITextView
(т.е. создание нового класса, который расширяет UITextView
), а затем реализовать метод selectAll
следующим образом:
- (void)selectAll:(id)sender {
[super selectAll:sender];
UITextRange *selectionRange = [self textRangeFromPosition:self.beginningOfDocument toPosition:self.endOfDocument];
[self performSelector:@selector(setSelectedTextRange:) withObject:selectionRange afterDelay:0.0];
}
Затем, когда вы используете текстовое представление, установите его тип в свой собственный тип текстового вида (в вашем коде и в раскадровке). Теперь вы можете успешно вызвать метод selectAll
всякий раз, когда вам нужно. Я полагаю, что это тоже должно работать с UITextField
, но я еще не пробовал.
Ответ 2
Это решение работает и не требует подкласса UITextView
, просто поместите эту функцию в свой делегат:
ЦЕЛЬ C -
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView {
dispatch_async(dispatch_get_main_queue(), ^{
[textView selectAll:nil];
});
return YES;
}
SWIFT 3 -
func textViewDidBeginEditing(_ textView: UITextView) {
DispatchQueue.main.async {
textView.selectAll(nil)
}
}
Ответ 3
Решение @brentvatne работало для меня. Публикация синтаксиса Swift, чтобы люди могли копировать и вставлять в будущем.
func textViewShouldBeginEditing(textView: UITextView) -> Bool {
dispatch_async(dispatch_get_main_queue()) {
textView.selectAll(nil)
}
return true
}