如何在UITextView中为特定单词(如//、let)设置不同颜色?
解决UITextView中特定单词单独着色的问题
我懂你现在的困扰——你想给UITextView里的特定关键词(比如//设红色、let设绿色)单独改颜色,但当前代码直接把整个文本的颜色都改了,根本做不到精准定位单个单词对吧?
先说说你原来代码的问题:textView.textColor是全局文本属性,一旦设置就会作用于所有内容,所以你遍历找到//后设置这个属性,自然会把所有文字都变成浅灰色,完全达不到单个单词着色的效果。
要实现局部文本着色,得用NSAttributedString(富文本)来处理,它可以给文本的不同范围设置独立的样式属性。下面是完整的实现方案:
核心思路
- 每次文本变化时,先基于当前文本创建可变富文本对象
NSMutableAttributedString - 先给整个文本设置默认颜色(比如黑色),避免之前的高亮样式残留
- 定义需要高亮的关键词和对应颜色的映射表
- 遍历每个关键词,找到文本中所有出现的位置,给对应范围单独设置颜色属性
- 最后把处理好的富文本赋值给
textView.attributedText
完整代码示例
func textViewDidChange(_ textView: UITextView) { // 先确保文本不为空 guard let currentText = textView.text else { return } // 创建可变富文本对象 let mutableAttributedText = NSMutableAttributedString(string: currentText) // 第一步:设置全局默认颜色(比如黑色) let fullTextRange = NSRange(location: 0, length: currentText.count) mutableAttributedText.addAttribute( .foregroundColor, value: UIColor.black, range: fullTextRange ) // 定义需要高亮的关键词与对应颜色 let highlightRules: [String: UIColor] = [ "//": .red, "let": .green // 可以继续添加更多关键词,比如"var": .blue之类的 ] // 遍历每个关键词,处理所有出现的位置 for (keyword, targetColor) in highlightRules { var searchRange = fullTextRange // 循环查找当前关键词的所有出现位置 while let foundRange = currentText.range( of: keyword, options: .caseInsensitive, // 如果需要区分大小写就去掉这个选项 range: Range(searchRange, in: currentText), locale: nil ) { // 把Swift的Range转换成NSRange let nsFoundRange = NSRange(foundRange, in: currentText) // 给这个范围设置目标颜色 mutableAttributedText.addAttribute( .foregroundColor, value: targetColor, range: nsFoundRange ) // 更新搜索范围,避免重复匹配同一个位置 searchRange = NSRange( location: nsFoundRange.location + nsFoundRange.length, length: fullTextRange.length - (nsFoundRange.location + nsFoundRange.length) ) } } // 把处理好的富文本赋值给TextView textView.attributedText = mutableAttributedText }
额外优化:避免新输入继承高亮颜色
上面的代码还有个小问题:如果光标停在高亮的单词后面,新输入的字符会继承这个高亮颜色。要解决这个问题,可以添加下面的代理方法,确保新输入的文本用默认颜色:
func textViewDidChangeSelection(_ textView: UITextView) { // 重置输入属性,让新输入的文本使用默认黑色 textView.typingAttributes = [.foregroundColor: UIColor.black] }
这样就能完美实现你想要的“特定单词单独着色”的效果啦!
内容的提问来源于stack exchange,提问作者user9620161
相关产品推荐
相关产品推荐

