Програмно виділіть увесь текст у UITextField


Відповіді:


59

Виявляється, зателефонувавши -selectAll: із ненульовим відправником відображається меню. Виклик його з нулем змушує його виділяти текст, але не відображати меню.

Я спробував це після того, як мій звіт про помилку про це повернувся від Apple із пропозицією передати нуль замість себе.

Не потрібно гадити з UIMenuController чи іншими API вибору.


3
Я намагався зрозуміти, як вибрати текст без відображення меню. Дякую, додавши це.
Ерік

1
Здається, це не працює для текстового поля контролера попереджень.
Ніколас Міарі,

3
Забудьте про це, для оповіщення контролерів цього відповідь працює: stackoverflow.com/a/35992115/433373
Ніколя Міар

1
+1 за правильну відповідь. Ще +1 за згадку про відправника та меню. Ще один +1 за згадку про джерело інформації. На жаль, я маю лише один голос ...
eonil

82

Ось що для мене зробило фокус:

[self.titleField setSelectedTextRange:[self.titleField textRangeFromPosition:self.titleField.beginningOfDocument toPosition:self.titleField.endOfDocument]];

Досить потворно, але це працює, тому не буде показано спільнийMenuController!

Щоб виправити проблему "працює лише кожен другий раз", використовуйте наступне:

__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
    __strong __typeof(weakSelf) strongSelf = weakSelf;
    UITextRange *range = [strongSelf textRangeFromPosition:strongSelf.beginningOfDocument toPosition:strongSelf.endOfDocument];
    [strongSelf setSelectedTextRange:range];
});

Дякую Еріку Бейкеру (щойно відредаговано з коментаря тут)


3
Це насправді набагато краща відповідь на запитання. Він робить те, про що просять, без жодних безглуздих обхідних шляхів, щоб запобігти показу меню (що в мене і так не працює).
PKCLsoft

1
Вибачте, що поверну це, але ваше рішення працює лише з першого разу. Вдруге це не вдалося. В основному, я зробив так, що коли користувачі натискають на UITextField, виділяють весь текст, щоб вони могли його замінити, вони можуть відхиляти клавіатуру, клацнувши щось інше (в цьому випадку прозорий фон), після цього натискання того самого UITextField не робити трюк більше. Повторіть цей процес, я помітив, що він працює в непарний час, але не працює в парний час. Тобто: працює для першого, третього, п’ятого; не працює на другий, четвертий, шостий.
LN

11
@LeonNguyen Це працює для мене, щоб вирішити проблему, яку ви описуєте: __weak typeof(self) weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ __strong __typeof(weakSelf) strongSelf = weakSelf; UITextRange *range = [strongSelf textRangeFromPosition:strongSelf.beginningOfDocument toPosition:strongSelf.endOfDocument]; [strongSelf setSelectedTextRange:range]; });
Ерік Бейкер

@EricBaker Я можу підтвердити, що ваше рішення спрацювало. Здається, це проблема з різьбою. Подяка
LN

1
__Слабкий / __сильний хак у мене не спрацював. Мені довелося скасувати вибір усього тексту після endEditing, щоб він міг бути свіжо виділеним при startEditing.
marsbear

48

Я щойно перевірив це, щоб перевірити коментар selectAll:Мірка вище, але мій тест перевіряє, що насправді виділяє весь текст, коли він надсилається до самого UITextField.

Зверніть увагу, що текст буде негайно затемнений за допомогою CUT | КОПІЮВАННЯ | ВСТАНОВИТИ дії, але на ваше запитання це саме те, що з’являється, коли користувач натискає "Вибрати все" для початку.

Рішення, з яким я піду, слід зазначити, що другий рядок тимчасово приховає діалогове вікно CUT / COPY / PASTE, не відключаючи його для явного вибору користувача

[_myTextField selectAll:self];
[UIMenuController sharedMenuController].menuVisible = NO;

Я хочу виділити весь текст, коли користувач натискає UITextField, щоб, як тільки вони почнуть друкувати, оригінальний текст стирався. До якої торгової точки я повинен закликати для досягнення цього? Я спробував зв’язати підключення всередині з IBAction, який викликає ваш код вище, але не працював.
C0D3

Гаразд, я зрозумів це, не турбуючись. Дякую.
C0D3

Тільки, щоб повідомити, що у мене це не спрацювало :( Меню все ще не видно, коли ми телефонуємо, [UIMenuController sharedMenuController].menuVisible = NO;так що ця лінія не матиме жодного ефекту.
Фабіо Олівейра,

3
Насправді, щоб виділити весь текст, щоб меню не відображалося, вам доведеться використовувати його setSelectedRange:.
Фабіо Олівейра,

47

Використовуйте те, що вам потрібно

ObjC

 [yourtextField becomeFirstResponder]; //puts cursor on text field

 [yourtextField selectAll:nil];  //highlights text

 [yourtextField selectAll:self]; //highlights text and shows menu(cut copy paste)

Стрімкий

yourTextField.becomeFirstResponder() //puts cursor on text field

yourTextField.selectAll(nil)  //highlights text

yourTextField.selectAll(self) //highlights text and shows menu(cut copy paste)

3
Найкраща відповідь тут. Надзвичайно простий і "нульовий" трюк, щоб приховати спливаюче вікно "Вирізати / Копіювати / Паштет" робить свою справу!
березень

1
Це найкраща / найпростіша відповідь
Хакмодфорд,

6
Зверніть увагу: якщо ви хочете виділити текст, коли вперше показуєте подання, ви повинні здійснити selectAllдзвінок viewDidAppear. Це не буде працювати, якщо розміщено в viewDidLoadабо viewWillAppear.
Бенджамін Мартін,

9

Це найкраще рішення, яке я знайшов. Немає sharedMenuController, і він працює послідовно:

-(void)textFieldDidBeginEditing:(UITextField *)textField
{
    [textField performSelector:@selector(selectAll:) withObject:nil afterDelay:0.1];
}

Додаючи відповідь через роки після того, як було задано питання, було б добре пояснити, чому ви додаєте ще одну відповідь. Тут є багато існуючих відповідей: за яких умов ваша відповідь "краща" за всі ці? Яка вигода? Чи бувають ситуації, коли це може бути не вигідно, і яку існуючу відповідь Ви б використали тоді?
ToolmakerSteve

4
Дякую! Цей підхід, а точніше Swift-еквівалент "textField.perform (#selector (selectAll), with: nil, afterDelay: 0.01)", виправляє проблему, яка виникала у Леона Нгуєна з відповіддю blackforestcowboy вище, де він працює лише кожен раз. Щось із затримкою дії повинно розібратися в нитках. Як каже @ToolmakerSteve, було б корисно пояснити це у відповіді тут.
Andy Mortimer

8

Стрімкий

Виділіть увесь текст у UITextField:

textField.selectedTextRange = textField.textRange(from: textField.beginningOfDocument, to: textField.endOfDocument)

Повна моя відповідь тут: https://stackoverflow.com/a/34922332/3681880


До речі, якщо існує Swift, еквівалентний коротшому альтернативному рішенню [textField selectAll:nil], було б непогано перерахувати це.
ToolmakerSteve

Так, якщо хтось це знає, будь ласка, залиште коментар.
Сурагч

3

Щоб мати змогу виділити текст, текстове поле має редагуватися. Щоб дізнатись, коли текстове поле можна редагувати, використовуйте методи делегування:

- (void)textFieldDidBeginEditing:(UITextField *)textField
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField

Я не думаю, що textFieldShouldBeginEditing: потрібно, але це те, що я використав у своїй реалізації.

- (void)textFieldDidBeginEditing:(UITextField *)textField{
    [textField selectAll:textField];
}

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
    return YES;
}

Перехід на нуль для вибору All: меню не відображатиметься.


2

На жаль, я не думаю, що ви можете це зробити.

Я не впевнений, чи це вам допомагає, але setClearsOnBeginEditingдозволяє вказати, що UITextFieldслід видалити існуюче значення, коли користувач почне редагувати (це типове значення для захисту UITextFields).



1

Я створюю власний подання сповіщення, яке містить UITextFieldвнутрішню частину . Я виявив, що проблема з текстовим полем полягає в тому, що: beginningOfDocumentмає значення лише в тому випадку, якщо текстове поле додано на екран і becomeFirstResponderвикликається.

В іншому випадку beginningOfDocumentповертається nilі[UITextField textRangeFromPosition:] не може отримати значення.

Отже, ось мій зразок коду для вирішення цієї справи.

UIWindow *window = [[[UIApplication sharedApplication] windows] firstObject];
[window addSubview:theAlertView]; // textfield must be added as a subview of screen first
UITextField *textField = theAlertView.textField;
[textField becomeFirstResponder]; // then call to show keyboard and cursor 
UITextRange *range = [textField textRangeFromPosition:textField.beginningOfDocument toPosition:textField.endOfDocument]; // at this time, we could get beginningOfDocument
[textField setSelectedTextRange:range]; // Finally, it works!!!

0
UITextField *tf = yourTF;
// hide cursor (you have store default color!!!)
[[tf valueForKey:@"textInputTraits"] setValue:[UIColor clearColor]
                                       forKey:@"insertionPointColor"];
// enable selection
[tf selectAll:self];
// insert your string here
// and select nothing (!!!)
[tf setMarkedText:@"Egor"
    selectedRange:NSMakeRange(0, 0)];

Готово!


-1

Якщо ви маєте на увазі, як би ви дозволили користувачеві редагувати текст у полі uitext, то просто призначте йому firstResponder:

[textField becomeFirstResponder]

Якщо ви маєте на увазі, як ви отримуєте текст у полі uitext, це зробить це:

textField.text

Якщо ви маєте на увазі насправді виділити текст (як підкреслити його), це може бути корисно:

вибрати все


Насправді я хочу виділити весь текст програмно (виділити), так само, як коли користувач натискає один раз на текст, а потім натискає на "Виділити все"
Мірко

Останній спосіб - це те, що ви тоді хочете.
Kendall Helmstetter Gelner

1
Насправді ні: Цей метод викликається, коли користувач натискає команду «Вибрати все» в меню редагування. Я хочу, щоб викликати Select All, як якщо користувач натиснув команду Select All.
Мірко
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.