Изменение цвета определенного текста с помощью NSMutableAttributedString в Swift


100

Проблема, с которой я столкнулся, заключается в том, что я хочу иметь возможность изменять textColor определенного текста в TextView. Я использую объединенную строку и просто хочу, чтобы строки, которые я добавляю в текст TextView. Похоже, что я хочу использовать именно это NSMutableAttributedString, но я не нахожу никаких ресурсов о том, как использовать это в Swift. Пока что у меня есть что-то вроде этого:

let string = "A \(stringOne) with \(stringTwo)"
var attributedString = NSMutableAttributedString(string: string)
textView.attributedText = attributedString

Отсюда я знаю, что мне нужно найти диапазон слов, для которых нужно изменить свой textColor, а затем добавить их в строку с атрибутами. Что мне нужно знать, так это как найти правильные строки из attributedString, а затем изменить их textColor.

Поскольку у меня слишком низкий рейтинг, я не могу ответить на свой вопрос, но вот ответ, который я нашел

Я нашел свой ответ, переведя из перевода некоторого кода из

Изменить атрибуты подстрок в NSAttributedString

Вот пример реализации на Swift:

let string = "A \(stringOne) and \(stringTwo)"
var attributedString = NSMutableAttributedString(string:string)

let stringOneRegex = NSRegularExpression(pattern: nameString, options: nil, error: nil)
let stringOneMatches = stringOneRegex.matchesInString(longString, options: nil, range: NSMakeRange(0, attributedString.length))
for stringOneMatch in stringOneMatches {
    let wordRange = stringOneMatch.rangeAtIndex(0)
    attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.nameColor(), range: wordRange)
}

textView.attributedText = attributedString

Поскольку я хочу изменить textColor нескольких строк, я сделаю вспомогательную функцию для обработки этого, но это работает для изменения textColor.


Вы знаете, как это сделать в Objective-C? Вы пытались переписать тот же код в Swift?
Аарон Брагер

Вот действительно хороший ответ: stackoverflow.com/a/37992022/426571
el_quick

Ответы:


110

Я вижу, вы несколько ответили на вопрос, но чтобы дать более сжатый способ без использования регулярного выражения для ответа на вопрос заголовка:

Чтобы изменить цвет длины текста, вам нужно знать начальный и конечный индексы символов, которые должны быть окрашены в строку, например

var main_string = "Hello World"
var string_to_color = "World"

var range = (main_string as NSString).rangeOfString(string_to_color)

Затем вы конвертируете в атрибутивную строку и используете 'add attribute' с NSForegroundColorAttributeName:

var attributedString = NSMutableAttributedString(string:main_string)
attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor() , range: range)

Список дополнительных стандартных атрибутов, которые вы можете установить, можно найти в документации Apple.


20
NSColor - это только OSX - используйте UIColor для IOS
Стив О'Коннор,

1
Что делать, если у меня есть var main_string = "Hello World Hello World Hello World" и мне нужно применить цвет к "World" во всей строке?
msmq

main_string, string_to_colorи rangeникогда не мутировали. Рассмотрите возможность их изменения на letпостоянные?
Чезаре

Хорошее решение. Ты спас мне день.
Сагар Чаухан

107
let mainString = "Hello World"
let stringToColor = "World"

SWIFT 5

let range = (mainString as NSString).range(of: stringToColor)

let mutableAttributedString = NSMutableAttributedString.init(string: mainString)
mutableAttributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.red, range: range)

textField = UITextField.init(frame: CGRect(x:10, y:20, width:100, height: 100))
textField.attributedText = mutableAttributedString

SWIFT 4.2

let range = (mainString as NSString).range(of: stringToColor)
    

let mutableAttributedString = NSMutableAttributedString.init(string: mainString)
mutableAttributedString.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.red, range: range)     
    
textField = UITextField.init(frame: CGRect(x:10, y:20, width:100, height: 100))
textField.attributedText = mutableAttributedString

что, если строка большая и в ней много повторяющихся (похожих) слов. будет диапазон (из: ...) работает?
Хатим

44

Обновление Swift 2.1:

 let text = "We tried to make this app as most intuitive as possible for you. If you have any questions don't hesitate to ask us. For a detailed manual just click here."
 let linkTextWithColor = "click here"

 let range = (text as NSString).rangeOfString(linkTextWithColor)

 let attributedString = NSMutableAttributedString(string:text)
 attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor() , range: range)

 self.helpText.attributedText = attributedString

self.helpTextэто UILabelрозетка.


1
О Крис, ты мой герой. Я давно ищу именно этот блок кода.
Pan Mluvčí

@chris. Я хочу изменить строку nsmutableattributed в текстовом представлении, возможно ли это
Ума Мадхави

это работает для одного слова. но в моей строке есть несколько слов, это изменение цвета, но затем я пишу после этого слова красного цвета, что цвет слова также красный. Так что вы можете дать любое решение, если у вас есть.
Дхавал Соланки

Спасибо за помощь!
ssowri1

19

Swift 4.2 и Swift 5 раскрашивают части веревки.

Очень простой способ использовать NSMutableAttributedString при расширении String. Это также можно использовать для окрашивания более одного слова во всей строке.

Добавьте новый файл для расширений, File -> New -> Swift File с именем, например. "NSAttributedString + TextColouring" и добавьте код

import UIKit

extension String {
    func attributedStringWithColor(_ strings: [String], color: UIColor, characterSpacing: UInt? = nil) -> NSAttributedString {
        let attributedString = NSMutableAttributedString(string: self)
        for string in strings {
            let range = (self as NSString).range(of: string)
            attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: color, range: range)
        }

        guard let characterSpacing = characterSpacing else {return attributedString}

        attributedString.addAttribute(NSAttributedString.Key.kern, value: characterSpacing, range: NSRange(location: 0, length: attributedString.length))

        return attributedString
    }
}

Теперь вы можете использовать глобально на любом контроллере просмотра, который хотите:

let attributedWithTextColor: NSAttributedString = "Doc, welcome back :)".attributedStringWithColor(["Doc", "back"], color: UIColor.black)

myLabel.attributedText = attributedWithTextColor

Пример использования раскраски текста в Swift 4


11

Ответ уже дан в предыдущих сообщениях, но у меня есть другой способ сделать это

Swift 3x:

var myMutableString = NSMutableAttributedString()

myMutableString = NSMutableAttributedString(string: "Your full label textString")

myMutableString.setAttributes([NSFontAttributeName : UIFont(name: "HelveticaNeue-Light", size: CGFloat(17.0))!
        , NSForegroundColorAttributeName : UIColor(red: 232 / 255.0, green: 117 / 255.0, blue: 40 / 255.0, alpha: 1.0)], range: NSRange(location:12,length:8)) // What ever range you want to give

yourLabel.attributedText = myMutableString

Надеюсь, это кому-нибудь поможет!


@UmaMadhavi Каковы ваши требования?
Анураг Шарма

Я хочу изменить размер и цвет шрифта в текстовом окне. Я получаю это в nsmutableattributedstring.
Ума Мадхави

@UmaMadhavi проверьте эту ссылку1 и ссылку2 . Может быть полезно!
Анураг Шарма

Вылетает, если шрифт недоступен.
SafeFastExpressive

10

Ответ Криса мне очень помог, поэтому я использовал его подход и превратил его в функцию, которую можно использовать повторно. Это позволило мне назначить цвет подстроке, а остальной части строки - другим цветом.

static func createAttributedString(fullString: String, fullStringColor: UIColor, subString: String, subStringColor: UIColor) -> NSMutableAttributedString
{
    let range = (fullString as NSString).rangeOfString(subString)
    let attributedString = NSMutableAttributedString(string:fullString)
    attributedString.addAttribute(NSForegroundColorAttributeName, value: fullStringColor, range: NSRange(location: 0, length: fullString.characters.count))
    attributedString.addAttribute(NSForegroundColorAttributeName, value: subStringColor, range: range)
    return attributedString
}

6

Swift 4.1

NSAttributedStringKey.foregroundColor

например, если вы хотите изменить шрифт в NavBar:

self.navigationController?.navigationBar.titleTextAttributes = [ NSAttributedStringKey.font: UIFont.systemFont(ofSize: 22), NSAttributedStringKey.foregroundColor: UIColor.white]

6

Вы можете использовать это расширение, которое я тестирую

быстрый 4.2

import Foundation
import UIKit

extension NSMutableAttributedString {

    convenience init (fullString: String, fullStringColor: UIColor, subString: String, subStringColor: UIColor) {
           let rangeOfSubString = (fullString as NSString).range(of: subString)
           let rangeOfFullString = NSRange(location: 0, length: fullString.count)//fullString.range(of: fullString)
           let attributedString = NSMutableAttributedString(string:fullString)
           attributedString.addAttribute(NSAttributedStringKey.foregroundColor, value: fullStringColor, range: rangeOfFullString)
           attributedString.addAttribute(NSAttributedStringKey.foregroundColor, value: subStringColor, range: rangeOfSubString)

           self.init(attributedString: attributedString)
   }

}

4

Swift 2.2

var myMutableString = NSMutableAttributedString()

myMutableString = NSMutableAttributedString(string: "1234567890", attributes: [NSFontAttributeName:UIFont(name: kDefaultFontName, size: 14.0)!])

myMutableString.addAttribute(NSForegroundColorAttributeName, value: UIColor(red: 0.0/255.0, green: 125.0/255.0, blue: 179.0/255.0, alpha: 1.0), range: NSRange(location:0,length:5))

self.lblPhone.attributedText = myMutableString

Я получаю сообщение об ошибке при этом. Я думаю, ты хочешь этого без .CGColor.
Бьорн Рош,

@SarabjitSingh. как это возможно для текстового просмотра
Ума Мадхави

@UmaMadhavi ... Вам просто нужно добавить self.textView.attributedText = myMutableString ..... Это будет работать ...
Сарабджит Сингх

4

Самый простой способ сделать метку с другим стилем, таким как цвет, шрифт и т. Д., - это использовать свойство «Attributed» в Attributes Inspector. Просто выберите часть текста и измените ее, как хотите

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


1
Предположим, вы не меняете струны программно
Алехандро Кампа

4

На основании ответов до того, как я создал расширение строки

extension String {

func highlightWordsIn(highlightedWords: String, attributes: [[NSAttributedStringKey: Any]]) -> NSMutableAttributedString {
     let range = (self as NSString).range(of: highlightedWords)
     let result = NSMutableAttributedString(string: self)

     for attribute in attributes {
         result.addAttributes(attribute, range: range)
     }

     return result
    }
}

Вы можете передать атрибуты текста в метод

Звоните так

  let attributes = [[NSAttributedStringKey.foregroundColor:UIColor.red], [NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: 17)]]
  myLabel.attributedText = "This is a text".highlightWordsIn(highlightedWords: "is a text", attributes: attributes)

4

Swift 4.1

Я изменил это в Swift 3

let str = "Welcome "
let welcomeAttribute = [ NSForegroundColorAttributeName: UIColor.blue()]
let welcomeAttrString = NSMutableAttributedString(string: str, attributes: welcomeAttribute)

И это в Swift 4.0

let str = "Welcome "
let welcomeAttribute = [ NSAttributedStringKey.foregroundColor: UIColor.blue()]
let welcomeAttrString = NSMutableAttributedString(string: str, attributes: welcomeAttribute)

в Swift 4.1

let str = "Welcome "
let welcomeAttribute = [ NSAttributedStringKey(rawValue: NSForegroundColorAttributeName): UIColor.blue()]
let welcomeAttrString = NSMutableAttributedString(string: str, attributes: welcomeAttribute)

Работает отлично


Это меняет всю строку? Это наиболее читаемый для меня, но есть ли способ изменить только определенные слова в строке, как попросил OP.
Moondra

3

быстрый 4.2

    let textString = "Hello world"
    let range = (textString as NSString).range(of: "world")
    let attributedString = NSMutableAttributedString(string: textString)

    attributedString.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.red, range: range)
    self.textUIlable.attributedText = attributedString

2

Для всех, кто ищет « Применение определенного цвета к нескольким словам в тексте », мы можем сделать это с помощью NSRegularExpression.

 func highlight(matchingText: String, in text: String) {
    let attributedString  = NSMutableAttributedString(string: text)
    if let regularExpression = try? NSRegularExpression(pattern: "\(matchingText)", options: .caseInsensitive) {
        let matchedResults = regularExpression.matches(in: text, options: [], range: NSRange(location: 0, length: attributedString.length))
        for matched in matchedResults {
             attributedString.addAttributes([NSAttributedStringKey.backgroundColor : UIColor.yellow], range: matched.range)

        }
        yourLabel.attributedText = attributedString
    }
}

Ссылка для справки: https://gist.github.com/aquajach/4d9398b95a748fd37e88


Можно ли использовать ваш код в приложении MacOS какао? Я пытался использовать его в своем проекте какао, но в какао NSTextView нет .attributedText.
CaOs433 03

2

Это может сработать для вас

let main_string = " User not found,Want to review ? Click here"
    let string_to_color = "Click here"

    let range = (main_string as NSString).range(of: string_to_color)

    let attribute = NSMutableAttributedString.init(string: main_string)
    attribute.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.blue , range: range)

    lblClickHere.attributedText = attribute

1
Хотя этот фрагмент кода может быть решением, включение объяснения действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин вашего предложения кода.
HMD

2

С помощью этой простой функции вы можете назначить текст и выделить выбранное слово.

Вы также можете изменить UITextView на UILabel и т. Д.

func highlightBoldWordAtLabel(textViewTotransform: UITextView, completeText: String, wordToBold: String){
    textViewToTransform.text = completeText
    let range = (completeText as NSString).range(of: wordToBold)
    let attribute = NSMutableAttributedString.init(string: completeText)

    attribute.addAttribute(NSAttributedString.Key.font, value: UIFont.boldSystemFont(ofSize: 16), range: range)
    attribute.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.black , range: range)
    textViewToTransform.attributedText = attribute
}

1

Чтобы изменить цвет цвета шрифта, сначала выберите атрибут с атрибутом вместо простого, как на изображении ниже.

Затем вам нужно выделить текст в поле с атрибутами, а затем нажать кнопку цвета с правой стороны выравнивания. Это изменит цвет.


1

Вы можете использовать этот метод. Я реализовал этот метод в своем общем служебном классе для глобального доступа.

func attributedString(with highlightString: String, normalString: String, highlightColor: UIColor) -> NSMutableAttributedString {
    let attributes = [NSAttributedString.Key.foregroundColor: highlightColor]
    let attributedString = NSMutableAttributedString(string: highlightString, attributes: attributes)
    attributedString.append(NSAttributedString(string: normalString))
    return attributedString
}

0

Если вы используете Swift 3x и UITextView, возможно, NSForegroundColorAttributeName не будет работать (у меня это не сработало, какой бы подход я ни пробовал).

Итак, покопавшись, я нашел решение.

//Get the textView somehow
let textView = UITextView()
//Set the attributed string with links to it
textView.attributedString = attributedString
//Set the tint color. It will apply to the link only
textView.tintColor = UIColor.red

0

Супер простой способ сделать это.

let text = "This is a colorful attributed string"
let attributedText = 
NSMutableAttributedString.getAttributedString(fromString: text)
attributedText.apply(color: .red, subString: "This")
//Apply yellow color on range
attributedText.apply(color: .yellow, onRange: NSMakeRange(5, 4))

Для получения более подробной информации нажмите здесь: https://github.com/iOSTechHub/AttributedString


0

Вам нужно изменить параметры textview, а не параметры атрибутированной строки

textView.linkTextAttributes = [
        NSAttributedString.Key.foregroundColor: UIColor.red,
        NSAttributedString.Key.underlineColor: UIColor.red,
        NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue
    ]

0

Пожалуйста, проверьте cocoapod Prestyler :

Prestyler.defineRule("$", UIColor.orange)
label.attributedText = "This $text$ is orange".prestyled()

0
extension String{
// to make text field mandatory * looks
mutating func markAsMandatoryField()-> NSAttributedString{

    let main_string = self
    let string_to_color = "*"
    let range = (main_string as NSString).range(of: string_to_color)
    print("The rang = \(range)")
    let attribute = NSMutableAttributedString.init(string: main_string)
    attribute.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.rgbColor(red: 255.0, green: 0.0, blue: 23.0) , range: range)
     return attribute
}

}

используйте EmailLbl.attributedText = EmailLbl.text! .markAsMandatoryField ()


0

Вы можете использовать как простое расширение

extension String{

func attributedString(subStr: String) -> NSMutableAttributedString{
    let range = (self as NSString).range(of: subStr)
    let attributedString = NSMutableAttributedString(string:self)
    attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.red , range: range)
    
    return attributedString
  }
}

myLable.attributedText = fullStr.attributedString(subStr: strToChange)

  
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.