UITextView更改特定文本的颜色

4

我想要改变UITextView中特定文本的颜色,该文本与数组的索引匹配。我能够稍微修改这个 答案 但不幸的是,每个匹配短语的文本颜色只会改变一次。

var chordsArray = ["Cmaj", "Bbmaj7"]
func getColoredText(textView: UITextView) -> NSMutableAttributedString {
    let text = textView.text
    let string:NSMutableAttributedString = NSMutableAttributedString(string: text)
    let words:[String] = text.componentsSeparatedByString(" ")
    for word in words {
        if (chordsArray.contains(word)) {
            let range:NSRange = (string.string as NSString).rangeOfString(word)
            string.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: range)
        }
    }
    chords.attributedText = string
    return string
}

结果
结果


NSAttributedString是你的答案。使用带有颜色属性的部分来实现着色,并将其组合为一个字符串。将其余部分放入普通的属性字符串中。现在将这两个属性字符串合并起来。 - NSNoob
是的,我是,而且没错 @NSNoob - kye
是的,我是的。该函数在textdidchange上被调用。 - kye
你能帮我做一个改动吗?在 optional func textViewDidEndEditing(_ textView: UITextView) 方法中调用 getColoredText 方法。另外,chords 是你的 textView 的名称吗? - NSNoob
抱歉,我使用的是Obj-C而不是Swift,所以可能会犯错。无论是什么过程,请按照它来添加目标方法到TextView,并给它这个控制事件UIControlEventEditingChanged。我认为你们应该像这样写:UIControlEvents.EditingChanged - NSNoob
显示剩余8条评论
3个回答

5

如果有人需要Swift 4的代码,以下是我从我的Xcode 9 Playground中获得的结果 :)

import UIKit
import PlaygroundSupport
class MyViewController : UIViewController
{
    override func loadView()
    {
        let view = UIView()
        view.backgroundColor = .white

        let textView = UITextView()
        textView.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
        textView.text = "@Kam @Jam @Tam @Ham"
        textView.textColor = .black
        view.addSubview(textView)
        self.view = view

        let query = "@"

        if let str = textView.text {
            let text = NSMutableAttributedString(string: str)
            var searchRange = str.startIndex..<str.endIndex
            while let range = str.range(of: query, options: NSString.CompareOptions.caseInsensitive, range: searchRange) {
                text.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.gray, range: NSRange(range, in: str))
                searchRange = range.upperBound..<searchRange.upperBound
            }
            textView.attributedText = text
        }
    }
}
PlaygroundPage.current.liveView = MyViewController()

我认为对于 Swift 3,您需要手动将 Range(String.Index) 转换为 NSRange,如下所示。
 let start = str.distance(from: str.startIndex, to: range.lowerBound)
 let len = str.distance(from: range.lowerBound, to: range.upperBound)
 let nsrange = NSMakeRange(start, len)
 text.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.gray, range: nsrange)

4

Swift 4.2 and 5

let string = "* Your receipt photo was not clear or did not capture the entire receipt details. See our tips here.\n* Your receipt is not from an eligible grocery, convenience or club store."
let attributedString = NSMutableAttributedString.init(string: string)
let range = (string as NSString).range(of: "See our tips")
attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.blue, range: range)
txtView.attributedText = attributedString
txtView.isUserInteractionEnabled = true
txtView.isEditable = false

输出

enter image description here


1
对于在代码中遇到NSAttributedString.Key.foregroundColor部分出现问题的人,请使用NSForegroundColorAttributeName代替。 - ACAkgul

2

抱歉,我刚刚注意到您的消息。这里有一个可用的示例(在游乐场中测试过):

import UIKit


func apply (string: NSMutableAttributedString, word: String) -> NSMutableAttributedString {
    let range = (string.string as NSString).rangeOfString(word)
    return apply(string, word: word, range: range, last: range)
}

func apply (string: NSMutableAttributedString, word: String, range: NSRange, last: NSRange) -> NSMutableAttributedString {
    if range.location != NSNotFound {
        string.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: range)
        let start = last.location + last.length
        let end = string.string.characters.count - start
        let stringRange = NSRange(location: start, length: end)
        let newRange = (string.string as NSString).rangeOfString(word, options: [], range: stringRange)
        apply(string, word: word, range: newRange, last: range)
    }
    return string
}

var chordsArray = ["Cmaj", "Bbmaj7"]
var text = "Cmaj Bbmaj7 I Love Swift Cmaj Bbmaj7 Swift"
var newText = NSMutableAttributedString(string: text)

for word in chordsArray {
    newText = apply(newText, word: word)
}

newText

我无法在Swift 2/Xcode 7中让这个例子运行。 - CM.
应该可以工作,除了拿这段代码并原封不动地使用之外,我没有做任何其他事情。 - IDev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接