iOS UITextView点击可变属性字符串对应句子变色及性能优化问题
问题1:点击获取整句范围并变色的实现
你可以直接在现有的textTapped方法中实现逻辑,步骤如下:
- 计算点击位置对应在textView文本中的字符索引
- 匹配到该索引所属的句子/段落范围
- 修改对应范围的富文本属性即可
示例代码:
// 先新增一个全局属性存储每个段落的范围,提前记录避免实时枚举 var paragraphRanges = [NSRange]() @objc func textTapped(_ sender:UITapGestureRecognizer) { guard let textView = sender.view as? UITextView else { return } // 获取点击位置对应的字符索引 let tapLocation = sender.location(in: textView) let charIndex = textView.layoutManager.characterIndex(for: tapLocation, in: textView.textContainer, fractionOfDistanceBetweenInsertionPoints: nil) guard charIndex != NSNotFound else { return } // 方式1:如果你要按系统语义的句子匹配,用枚举句子的方法 guard let text = textView.text else { return } let fullRange = NSRange(location: 0, length: text.utf16.count) var targetRange = NSRange() text.enumerateSubstrings(in: Range(fullRange, in: text)!, options: .bySentences) { substring, range, _, stop in if NSLocationInRange(charIndex, NSRange(range, in: text)) { targetRange = NSRange(range, in: text) stop.pointee = true } } // 方式2:更符合你业务场景的方案,直接匹配提前记录的段落范围(推荐) // for range in paragraphRanges { // if NSLocationInRange(charIndex, range) { // targetRange = range // break // } // } guard targetRange.location != NSNotFound else { return } // 修改整句/整段颜色 let mutableAttr = NSMutableAttributedString(attributedString: textView.attributedText) mutableAttr.addAttribute(.foregroundColor, value: UIColor.red, range: targetRange) textView.attributedText = mutableAttr }
需要提前记录段落范围的话,在你生成富文本的循环里追加如下逻辑:
Array(1..<50).forEach { let start = attributedString.length // 原有添加文本、添加附件的逻辑不变 // ... let end = attributedString.length paragraphRanges.append(NSRange(location: start, length: end - start)) }
问题2:性能更优的UI实现方案
- 段落数量在100以内的话,现有UITextView方案性能足够,不需要额外调整
- 段落数量更多、内容更长的场景,推荐使用UITableView复用方案:
- 每个带编号的段落对应一个TableViewCell,cell内部分别用UILabel/UIImageView承载文本和编号,不需要生成NSTextAttachment,内存占用更低
- 关闭TableView的分隔线,开启自动行高,滚动时系统会自动复用cell,不会一次性加载所有内容到内存,滚动流畅度远高于单个UITextView加载超长文本
- 如果需要保留跨段落选中文本等整段文本交互特性,可以用TextKit的区域渲染能力,仅渲染当前可视区域+上下少量预加载区域的文本,无需一次性加载全部内容。
内容的提问来源于stack exchange,提问作者sheko
相关产品推荐
相关产品推荐

