如何更改标签中每5个头一个单词的文本颜色?

时间:2019-06-26 15:44:57

标签: swift uilabel uicolor

我从API中获得了不同的文本,我想为每5个第一个单词更改文本颜色。我尝试使用范围和属性字符串,但是我做错了,这对我来说不是一件好事。我该怎么办?

这是我的代码:

private func setMessageText(text: String) {
    let components = text.components(separatedBy: .whitespacesAndNewlines)
    let words = components.filter { !$0.isEmpty }

    if words.count >= 5 {
        let attribute = NSMutableAttributedString.init(string: text)

        var index = 0
        for word in words where index < 5 {

            let range = (text as NSString).range(of: word, options: .caseInsensitive)
            attribute.addAttribute(NSAttributedString.Key.foregroundColor, value: Colors.TitleColor, range: range)
            attribute.addAttribute(NSAttributedString.Key.font, value: Fonts.robotoBold14, range: range)
            index += 1
        }
        label.attributedText = attribute
    } else {
        label.text = text
    }
}

enter image description here

1 个答案:

答案 0 :(得分:1)

获取第5个单词末尾的索引并为整个范围添加一次颜色和字体会更有效。

强烈不建议将String桥接到NSString以从字符串中获取子范围。 不要这样做。使用本机Swift Range<String.Index>,有一个便捷的API可将Range<String.Index>可靠地转换为NSRange

private func setMessageText(text: String) {
    let components = text.components(separatedBy: .whitespacesAndNewlines)
    let words = components.filter { !$0.isEmpty }

    if words.count >= 5 {
        let endOf5thWordIndex = text.range(of: words[4])!.upperBound
        let nsRange = NSRange(text.startIndex..<endOf5thWordIndex, in: text)

        let attributedString = NSMutableAttributedString(string: text)
        attributedString.addAttributes([.foregroundColor : Colors.TitleColor, .font : Fonts.robotoBold14], range: nsRange)
        label.attributedText = attributedString
    } else {
        label.text = text
    }
}

一种更复杂的方法是使用专用API enumerateSubstrings(in:options:和选项byWords

func setMessageText(text: String) {

    var wordIndex = 0
    var attributedString : NSMutableAttributedString?
    text.enumerateSubstrings(in: text.startIndex..., options: .byWords) { (substring, substringRange, enclosingRange, stop) in
        if wordIndex == 4 {
            let endIndex = substringRange.upperBound
            let nsRange = NSRange(text.startIndex..<endIndex, in: text)
            attributedString = NSMutableAttributedString(string: text)
            attributedString!.addAttributes([.foregroundColor : Colors.TitleColor, .font : Fonts.robotoBold14], range: nsRange)
            stop = true
        }
        wordIndex += 1
    }

    if let attributedText = attributedString {
       label.attributedText = attributedText
    } else {
       label.text = text
    }
}