以编程方式选择UITextField中的所有文本


Answers:


59

原来,调用-selectAll:使用非零发送者显示菜单。用nil调用它会使它选择文本,但不显示菜单。

在我的bug报告从Apple回来后,我建议我通过nil而不是self来尝试。

无需考虑UIMenuController或其他选择API。


3
我一直在试图找出如何选择文本而不显示菜单。谢谢你添加那个小玩意儿。
埃里克(Erik)2015年

1
似乎不适用于警报控制器的文本字段。
Nicolas Miari '16

3
忘记了,对于警报控制器,此答案有效:stackoverflow.com/a/35992115/433373
Nicolas Miari

1
+1为正确答案。另一个+1,用于提及发件人和菜单。提及信息来源的另一个+1。可悲的是,我只有一票...-
尼尔

82

那就是我的诀窍:

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

很难看,但是它可以工作,所以不会显示sharedMenuController!

要解决“仅第二次才有效”的问题,请使用以下命令:

__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];
});

感谢Eric Baker(刚刚从这里的评论中编辑)


3
实际上,这是对该问题的更好的答案。它没有任何愚蠢的解决方法就能完成所要求的操作,以防止显示菜单(无论如何我都无法使用)。
PKCLsoft

1
很抱歉,将其恢复,但您的解决方案仅在第一次使用时有效。第二次,它失败了。基本上,我所做的是,当用户单击UITextField时,选择所有文本以便可以覆盖所有文本,可以通过单击其他内容(在这种情况下为透明背景)来关闭键盘,然后单击同一UITextField不会再做个窍门。重复此过程,我注意到它适用于奇数时间,但不适用于偶数时间。即:适用于第一,第三,第五;不适用于第二,第四,第六。
2013年

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]; });
Eric Baker

@EricBaker我可以确认您的解决方案有效。这似乎是线程问题。谢谢
LN

1
__weak / __strong hack对我不起作用。我必须在endEditing上取消选择所有文本,以便可以在startEditing上重新选择它。
marsbear 2015年

48

我刚刚进行了测试,以验证Mirko的上述评论,但是我的测试验证了selectAll:发送给UITextField本身时确实选择了所有文本。

请注意,文本将立即被CUT |隐藏。复制| 粘贴动作,但是您的问题恰恰是用户点击“全选”时出现的内容。

我要使用的解决方案如下,请注意,第二行将暂时隐藏“ CUT / COPY / PASTE”对话框,而不会为明确的用户选择禁用它

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

我想在用户点击UITextField时选择所有文本,以便一旦他们开始键入,原始文本就会被删除。为了达到这个目的,我应该采取哪种行动?我尝试将补全链接到IBAction,后者在上面调用了您的代码,但是没有用。
C0D3 2012年

好吧,我知道没有后顾之忧。谢谢。
C0D3'1

只是想让您知道它对我不起作用:(我们打电话时菜单仍然不可见,[UIMenuController sharedMenuController].menuVisible = NO;因此该行不会产生任何影响。
FábioOliveira

3
实际上,要选择所有文本以便不显示菜单,您必须使用它setSelectedRange:
法比奥奥利维拉

47

使用您所需要的

对象

 [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
最好的答案在这里。超级简单,隐藏隐藏“剪切/复制/页”弹出窗口的“零”技巧就可以了!
2014年

1
这是最好/最简单的答案
Hackmodford,2015年

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),带有:nil,afterDelay:0.01)”,解决了Leon Nguyen在blackforestcowboy上面的回答中遇到的问题,该问题只能每隔一段时间运行一次。关于延迟动作的某些事情必须理清线程。正如@ToolmakerSteve所说,在此处的答案中进行解释将很有用。
安迪·莫蒂默

8

迅速

选择所有文本UITextField

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

我的完整答案在这里:https : //stackoverflow.com/a/34922332/3681880


顺便说一句,如果有一个Swift等效于更短的替代解决方案[textField selectAll:nil],也可以列出它。
ToolmakerSteve

是的,如果有人知道,请发表评论。
Suragch '17

3

为了能够选择文本,文本字段必须是可编辑的。要知道何时可以编辑文本字段,请使用委托方法:

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

我不认为textFieldShouldBeginEditing:是必需的,但这是我在实现中使用的。

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

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

将nil传递给selectAll:不会显示菜单。


2

不幸的是,我认为您无法做到这一点。

我不确定这是否对您有帮助,但setClearsOnBeginEditing可以让您指定,UITextField当用户开始编辑时(应该是secure的默认值),应当删除现有值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

如果您是说要如何允许用户编辑uitextfield中的文本,则只需为其分配firstResponder即可:

[textField becomeFirstResponder]

如果您的意思是如何在uitextfield中获取文本,那么它将执行以下操作:

textField.text

如果您的意思是实际选择文本(如突出显示),那么这可能会很有用:

全选


实际上,我想以编程方式(突出显示)选择所有文本,这与用户在文本上点击一次然后点击“全选”相同
Mirko

最后一种方法就是您想要的。
Kendall Helmstetter Gelner,2009年

1
实际上不是:当用户点击编辑菜单的“全选”命令时,将调用此方法。我想要的是调用全选,就像用户点击全选命令一样。
Mirko,2009年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.