You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在UITextView中为特定单词(如//、let)设置不同颜色?

解决UITextView中特定单词单独着色的问题

我懂你现在的困扰——你想给UITextView里的特定关键词(比如//设红色、let设绿色)单独改颜色,但当前代码直接把整个文本的颜色都改了,根本做不到精准定位单个单词对吧?

先说说你原来代码的问题:textView.textColor是全局文本属性,一旦设置就会作用于所有内容,所以你遍历找到//后设置这个属性,自然会把所有文字都变成浅灰色,完全达不到单个单词着色的效果。

要实现局部文本着色,得用NSAttributedString(富文本)来处理,它可以给文本的不同范围设置独立的样式属性。下面是完整的实现方案:

核心思路

  1. 每次文本变化时,先基于当前文本创建可变富文本对象NSMutableAttributedString
  2. 先给整个文本设置默认颜色(比如黑色),避免之前的高亮样式残留
  3. 定义需要高亮的关键词和对应颜色的映射表
  4. 遍历每个关键词,找到文本中所有出现的位置,给对应范围单独设置颜色属性
  5. 最后把处理好的富文本赋值给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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:34:33