Как я могу изменить цвет текста для каждых 5 первых слов в ярлыке? - PullRequest
0 голосов
/ 26 июня 2019

Я получаю другой текст из 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
    }
}

введите описание изображения здесь

1 Ответ

1 голос
/ 26 июня 2019

Более эффективно получить индекс конца 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
    }
}
...