UITextView双击选中多词问题:如何强制仅选中单个单词?
解决UITextView双击选中整个首字母大写短语的问题
UITextView默认的文本分词逻辑会把首字母大写的连续词组(比如"United States")识别为一个整体,导致双击时选中整个短语。要实现双击仅选中单个单词,你可以通过自定义UITextView的手势处理来覆盖默认行为。
实现步骤
创建一个UITextView的子类,拦截双击手势并手动计算单个单词的选中范围:
import UIKit class SingleWordSelectTextView: UITextView { override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { // 拦截双击手势 if let tapGesture = gestureRecognizer as? UITapGestureRecognizer, tapGesture.numberOfTapsRequired == 2 { let tapLocation = tapGesture.location(in: self) guard let textPosition = closestPosition(to: tapLocation) else { return super.gestureRecognizerShouldBegin(gestureRecognizer) } // 从点击位置获取文本索引,手动确定单个单词的边界 let text = self.text ?? "" let charOffset = offset(from: beginningOfDocument, to: textPosition) guard charOffset < text.count else { return super.gestureRecognizerShouldBegin(gestureRecognizer) } var start = charOffset // 向前遍历,找到第一个非字母/数字的字符 while start > 0, text[text.index(text.startIndex, offsetBy: start-1)].isLetter || text[text.index(text.startIndex, offsetBy: start-1)].isNumber { start -= 1 } var end = charOffset // 向后遍历,找到第一个非字母/数字的字符 while end < text.count, text[text.index(text.startIndex, offsetBy: end)].isLetter || text[text.index(text.startIndex, offsetBy: end)].isNumber { end += 1 } // 设置选中范围为单个单词 selectedRange = NSRange(location: start, length: end - start) return false // 阻止默认的选中逻辑 } return super.gestureRecognizerShouldBegin(gestureRecognizer) } }
使用方式
- 代码中初始化:直接创建
SingleWordSelectTextView实例,替代原来的UITextView - Storyboard/Xib中:选中UITextView控件,在Identity Inspector里将Class改为
SingleWordSelectTextView
这样处理后,无论单词是否首字母大写,双击都会只选中单个连续的字母/数字序列,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Ken Franklin
相关产品推荐
相关产品推荐

