我可以在 UITextField 中选择特定的文本块吗?

Posted

技术标签:

【中文标题】我可以在 UITextField 中选择特定的文本块吗?【英文标题】:Can I select a specific block of text in a UITextField? 【发布时间】:2011-03-17 16:37:32 【问题描述】:

我的 iPhone 应用中有一个 UITextField。我知道如何使文本字段选择其所有文本,但如何更改选择?假设我想选择最后 5 个字符或特定范围的字符,这可能吗?如果不是,我可以移动标记选择开始和结束的线条,就像用户拖动它们一样?

【问题讨论】:

嘿.. 你能告诉我如何让文本字段选择它的所有文本 @AjaySharma, Select all text in text field(我相信你不再需要知道了,但还没有其他人回答过这条评论。) 【参考方案1】:

使用 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];

【讨论】:

我不太明白你的意思。既然你说文本字段不可能,我尝试使用一个文本视图,它确实有一个 selectedRange 字段,尽管我似乎无法让 getter 或 setter 工作。例如:txtDescription.selectedRange = NSMakeRange(0, 5);我希望这会选择 txtDescription 中的前 5 个字符,这是一个 UITextView*,但事实并非如此。有什么想法吗? 没关系,我用不涉及文本选择的不同方法解决了我的问题。无论如何感谢您的建议。 顺便说一句,当 textView 是第一响应者时 selectedRange 工作(例如在编辑时)。询问 selectedRange ,如果有选择,您将获得光标位置或选择范围。设置它,光标会改变;) @Sunian314 :您好,您能介绍一下解决您问题的方法吗? 我真正想做的是将文本完成功能添加到一个文本字段中,以模仿浏览器中地址栏的功能,因此如果用户键入“He”并且他们之前输入了“Hello ",然后 "Hello" 将显示在文本字段中,但最后的 "llo" 将被选中,以便用户可以继续输入以防万一他的意思是别的。因为我不能让它工作,我决定创建一个按钮,弹出完成的剩余字母,所以在这种情况下,一个按钮会弹出一个带有文本“llo”的用户可以点击删除那些中的字母。【参考方案2】:

要选择特定范围的字符,您可以在 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 元素都有自己的私有子类 UITextPositionUITextRange,因此您无法直接创建新值,但您可以使用文本字段从参考中为您创建它们文本的开头或结尾以及一个整数偏移量。

您也可以反过来获取当前选择的起点和终点的整数表示:

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

【讨论】:

【参考方案3】:

要选择不带文件扩展名的文件名,请使用:

-(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];

【讨论】:

使用self.filename.stringByDeletingPathExtension.length而不是[self.filename length] - [[self.filename pathExtension] length] - 1,代码可能会更简单。【参考方案4】:

这些都对我有用:

[UITextField selectAll:self];

和:

UITextField.selectedRange = NSMakeRange(0, 5);

但仅当文本字段是第一响应者时。 (换句话说,仅当键盘显示时。)因此,您需要在任一选择方法之前使用:

[UITextField becomeFirstResponder];

如果您希望文本显示为选中状态。

【讨论】:

这似乎适用于UITextView,但不适用于UITextField。还是你知道一些我不知道的事情? selectAll: 是 UITextField 采用的 UIResponderStandardEditActions 非正式协议的一部分。 selectedRange 不是 UITextField 的属性,尽管 selectedTextRange 是,正如上面 nacho4d 的更新所涵盖的那样。【参考方案5】:

只是对已接受答案的一小部分补充。在 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];

【讨论】:

【参考方案6】:

斯威夫特

选择最后 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!)

我的完整答案是here。

【讨论】:

【参考方案7】:

Swift 5.0

这是我从Panda.txt中选择文件名Panda的方法

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!)


【讨论】:

相信我,这很有用,我不知道为什么它没有投票

以上是关于我可以在 UITextField 中选择特定的文本块吗?的主要内容,如果未能解决你的问题,请参考以下文章

UITextfield 模仿下拉(UITableView?)

如何在警报中访问 Uitextfield 的文本?

在通过数据源创建的 UITextField 中显示占位符文本

在 uitextfield 中禁用查找和共享文本选择

在键盘应用程序扩展中使用 UITextField

编辑时如何更改 UITextField