web-dev-qa-db-fra.com

Modification de la couleur d'un texte spécifique à l'aide de NSMutableAttributedString dans Swift

Le problème que je rencontre est que je veux pouvoir modifier le textColor de certains textes dans un TextView. J'utilise une chaîne concaténée et je veux juste les chaînes que j'ajoute dans le texte de TextView. Il semble que ce que je veux utiliser soit NSMutableAttributedString, mais je ne trouve aucune ressource sur la façon de l'utiliser dans Swift. Ce que j'ai jusqu'ici ressemble à ceci:

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

À partir de là, je sais que je dois trouver la gamme de mots qui doivent avoir leur textColor modifié, puis les ajouter à la chaîne attribuée. Ce que j'ai besoin de savoir, c'est comment trouver les chaînes correctes à partir de l'attribut attribuéString, puis changer leur textColor.

Comme ma note est trop basse, je ne peux pas répondre à ma propre question, mais voici la réponse que j'ai trouvée

J'ai trouvé ma propre réponse en traduisant en traduisant du code de 

Changer les attributs des sous-chaînes dans un NSAttributedString

Voici l'exemple d'implémentation dans 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

Puisque je veux changer le textColor de plusieurs chaînes, je vais créer une fonction d'assistance pour gérer cela, mais cela fonctionne pour changer le textColor. 

73
richyrich24

Je vois que vous avez un peu répondu à la question, mais pour fournir un moyen légèrement plus concis sans utiliser regex pour répondre à la question du titre:

Pour changer la couleur d'une longueur de texte, vous devez connaître les index de début et de fin des caractères de couleur à être dans la chaîne, par ex.

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

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

Ensuite, vous convertissez en chaîne attribuée et utilisez 'add attribute' avec NSForegroundColorAttributeName:

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

Vous trouverez une liste des autres attributs standard que vous pouvez définir dans Documentation Apple

90
james_alvarez

Swift 4.2

 let txtfield1 :UITextField!

    let main_string = "Hello World"
    let string_to_color = "World"

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

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


    txtfield1 = UITextField.init(frame:CGRect(x:10 , y:20 ,width:100 , height:100))
    txtfield1.attributedText = attribute
62
Kishore Kumar

Mise à jour 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 est une sortie UILabel.

41
Chris

La réponse est déjà donnée dans les précédents posts mais j'ai une façon différente de le faire

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

J'espère que cela aide n'importe qui!

10
Anurag Sharma

La réponse de Chris m'a été d'une grande aide. J'ai donc utilisé son approche et transformé en une fonction que je peux réutiliser. Cela me permet d’affecter une couleur à une sous-chaîne tout en donnant une autre couleur au reste de la chaîne.

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
}
7
ghostatron

Swift 4.1

NSAttributedStringKey.foregroundColor

par exemple, si vous souhaitez modifier la police dans NavBar:

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

Vous pouvez utiliser cette extension Je la teste 

Swift 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)
   }

}
3
Amr Angry

Basé sur les réponses avant que je crée une extension de chaîne

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
    }
}

Vous pouvez transmettre les attributs du texte à la méthode.

Appelle comme ça

  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)
3
kuzdu

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
3
Sarabjit Singh

Un moyen très simple d'utiliser NSMutableAttributedString lors de l'extension de String. Solution dans Swift 4.2, mais je pense que c'est également facile à gérer dans d'autres versions de Swift. Ceci peut également être utilisé pour colorer plus d'un mot dans une chaîne entière.

Ajouter un nouveau fichier pour les extensions, Fichier -> Nouveau -> Nouveau fichier avec le nom ex. "NSAttributedString + TextColouring" et ajoutez le code

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
    }
}

Vous pouvez maintenant utiliser globalement le contrôleur de vue de votre choix:

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

myLabel.attributedText = attributedWithTextColor

 Example of using text colouring with Swift 4

2
Doca

Swift 4.1

J'ai changé de celaIn Swift 3

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

Et ceci dans 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)

Fonctionne bien

2
niravdesai21

Pour tous ceux qui recherchent "application d'une couleur spécifique à plusieurs mots dans le texte} [", nous pouvons le faire à l'aide de 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
    }
}

Lien de référence: https://Gist.github.com/aquajach/4d9398b95a748fd37e88

1
cgeek

Le moyen le plus simple de créer des libellés avec différents styles, tels que la couleur, la police, etc., consiste à utiliser la propriété "Attribué" dans l'inspecteur des attributs. Il suffit de choisir une partie du texte et de la modifier comme vous le souhaitez

 enter image description here

1
jMelvins

Swift 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
1
Giang

Cela pourrait être un travail pour vous

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

Si vous utilisez Swift 3x et UITextView, peut-être que NSForegroundColorAttributeName ne fonctionnera pas (cela ne fonctionna pas pour moi, quelle que soit l'approche choisie).

Donc, après quelques recherches, j'ai trouvé une solution.

//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
mcastro

Vous devez modifier les paramètres textview, pas les paramètres de la chaîne attribuée.

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

Vous pouvez utiliser cette méthode. J'ai implémenté cette méthode dans ma classe d'utilitaire commun pour un accès global. 

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
iDev750

S'il vous plaît vérifier cocoapod Prestyler :

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

Super moyen facile de faire cela.

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))

Pour plus de détails, cliquez ici: https://github.com/iOSTechHub/AttributedString

0
Ashish Chauhan

Pour changer la couleur de la couleur de la police, sélectionnez d'abord attribut au lieu de plaine comme dans l'image ci-dessous

Vous devez ensuite sélectionner le texte dans le champ attribué, puis le bouton de couleur situé à droite des alignements. Cela va changer la couleur.

 

0
Kingsley Mitchell