使用 NSMutableAttributedString 为字符串中的单词添加颜色

Adding color to a word in string using NSMutableAttributedString

我正在尝试为字符串中的 2 个单词添加颜色。这是我使用的代码:

        var HighScore:Int = 0
        var CurrentScore:Int = 0

        let stringOne = "You have managed to score \(CurrentScore). Current record is \(self.HighScore). Play again and give it another try!"
        let stringTwo = "\(CurrentScore)"
        let stringThree = "\(HighScore)"

        let range1 = (stringOne as NSString).range(of: stringTwo)
        let range2 = (stringOne as NSString).range(of: stringThree)

        let attributedText = NSMutableAttributedString.init(string: stringOne)

        attributedText.addAttribute(NSForegroundColorAttributeName, value: UIColor.init(netHex: 0x00b4ff) , range: range1)
        attributedText.addAttribute(NSForegroundColorAttributeName, value: UIColor.init(netHex: 0x00b4ff) , range: range2)

        gameOverDescriptionLabel.attributedText = attributedText

我遇到的问题是,如果 CurrentScoreHighScore 相同(例如:2 和 2),range2 上的颜色仍然是白色,但如果它们是不等于(2 & 1 或 1 & 2)都得到我选择的颜色。

有什么建议吗?

如果当前分数和最高分是同一个字符串,则搜索后者会找到前者(因为搜索从头开始)。

还有很多其他更好的方法可以做到这一点。

  • 在第一次搜索结果之后执行第二次搜索(range(of:)有一个range: parameter,但是你没有使用它)

  • 不是寻找高分的范围,而是搜索周围的样板("You have managed to score" 等等)并找出数字必须在哪里。

  • 使用NSScanner或正则表达式查找字符串中嵌入的数值表达式。

  • 我最喜欢的:用 "invisible" 属性标记每个数字并搜索该属性,以便您可以可靠地找到数字(示例 here)。

不搜索范围的解决方案是为当前分数和最高分数创建 2 个单独的 NSMutableAttributedString,然后将所有内容附加在一起。

let currentScoreString = NSMutableAttributedString(...)
let highscoreString = NSMutableAttributedString(...)

let finalString = NSMutableAttributedString(string: "You have managed to score ").append(currentScoreString)....

将此添加到 .swift 文件的顶部或底部:

extension NSMutableAttributedString {
    func bold(_ text:String) -> NSMutableAttributedString {
        let attrs:[String:AnyObject] = [NSForegroundColorAttributeName: UIColor.init(netHex: 0x00b4ff)]
        let boldString = NSMutableAttributedString(string:"\(text)", attributes:attrs)
        self.append(boldString)
        return self
    }

    func normal(_ text:String)->NSMutableAttributedString {
        let normal =  NSAttributedString(string: text)
        self.append(normal)
        return self
    }
}

下面的代码是用法,您可以随意编辑它,但我已经做到了,您只需将其复制并粘贴到您的项目中即可:

            let formattedString = NSMutableAttributedString()
            formattedString
                .normal("You have managed to score ")
                .bold("\(CurrentScore)")
                .normal(". Current record is ")
                .bold("\(HighScore)")
                .normal(". Play again and give it another try!")

            gameOverDescriptionLabel.attributedText = formattedString
//MARK: forgroundColor

open var foregroundColor: UIColor? {
    didSet {
        textAttributes[NSForegroundColorAttributeName] = foregroundColor
        self.attributedText = NSAttributedString(string: self.text, attributes: textAttributes)
    }
}

//MARK: backgroundColor
open var textBackgroundColor: UIColor? {
    didSet {
        textAttributes[NSBackgroundColorAttributeName] = textBackgroundColor
        self.attributedText = NSAttributedString(string: self.text, attributes: textAttributes)
    }
}