Modifica del colore di un testo specifico utilizzando NSMutableAttributedString in Swift


100

Il problema che sto riscontrando è che voglio essere in grado di cambiare il textColor di un determinato testo in un TextView. Sto usando una stringa concatenata e voglio solo le stringhe che sto aggiungendo al testo di TextView. Sembra che quello che voglio usare sia NSMutableAttributedString, ma non trovo alcuna risorsa su come usarlo in Swift. Quello che ho finora è qualcosa del genere:

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

Da qui so che ho bisogno di trovare l'intervallo di parole che devono cambiare il loro textColor e quindi aggiungerle alla stringa attribuita. Quello che ho bisogno di sapere è come trovare le stringhe corrette da attributeString e quindi modificare il loro textColor.

Dato che ho una valutazione troppo bassa non posso rispondere alla mia domanda, ma ecco la risposta che ho trovato

Ho trovato la mia risposta traducendo dalla traduzione del codice da

Modificare gli attributi delle sottostringhe in un NSAttributedString

Ecco l'esempio di implementazione in 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

Dato che voglio cambiare textColor di più stringhe, creerò una funzione di supporto per gestirlo, ma funziona per cambiare textColor.


Sai come farlo in Objective-C? Hai tentato di riscrivere lo stesso codice in Swift?
Aaron Brager

Ecco una veramente buona risposta: stackoverflow.com/a/37992022/426571
el_quick

Risposte:


110

Vedo che hai risposto in qualche modo alla domanda, ma per fornire un modo leggermente più conciso senza usare regex per rispondere alla domanda del titolo:

Per cambiare il colore di una lunghezza di testo devi conoscere l'indice iniziale e finale dei caratteri da colorare nella stringa ad es.

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

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

Quindi si converte in stringa attribuita e si utilizza "aggiungi attributo" con NSForegroundColorAttributeName:

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

Un elenco di ulteriori attributi standard che puoi impostare è disponibile nella documentazione di Apple


20
NSColor è solo OSX - usa UIColor per IOS
Steve O'Connor

1
Cosa succede se ho var main_string = "Hello World Hello World Hello World" e devo applicare il colore a "World" nell'intera stringa?
msmq

main_string, string_to_colorE rangenon sono mai stati mutati. Considera l'idea di cambiarli in letcostanti?
Cesare

Bella soluzione. Mi hai salvato la giornata.
Sagar Chauhan

106

SWIFT 5

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(NSAttributedString.Key.foregroundColor, value: UIColor.red , range: range)


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

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

cosa succede se la stringa è grande e contiene molte parole duplicate (simili). la gamma (di: ...) funziona?
Hatim

44

Aggiornamento 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è uno UILabelsbocco.


1
Oh Chris, tu sei il mio eroe. Sto cercando questo blocco di codice esattamente da molto tempo.
Pan Mluvčí

@Chris . Voglio cambiare la stringa nsmutableattributed in textview, è possibile
Uma Madhavi

funziona per una singola parola, ma nella mia stringa ci sono più parole, cambia colore ma poi scrivo dopo quella parola di colore rosso anche il colore della parola è rosso, quindi puoi dare qualche soluzione se lo hai.
Dhaval Solanki

Grazie per l'aiuto!
ssowri1

18

Swift 4.2 e Swift 5 colorano parti della corda.

Un modo molto semplice per usare NSMutableAttributedString mentre si estende String. Questo può anche essere usato per colorare più di una parola nell'intera stringa.

Aggiungi un nuovo file per le estensioni, File -> Nuovo -> Swift File con nome per es. "NSAttributedString + TextColouring" e aggiungi il codice

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

Ora puoi utilizzare globalmente in qualsiasi viewcontroller che desideri:

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

myLabel.attributedText = attributedWithTextColor

Esempio di utilizzo della colorazione del testo con swift 4


11

La risposta è già stata data nei post precedenti, ma ho un modo diverso di farlo

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

Spero che questo aiuti qualcuno!


@UmaMadhavi Qual è esattamente la tua esigenza?
Anurag Sharma

Voglio cambiare la dimensione del carattere e il colore del carattere nella visualizzazione testo. Lo ricevo in nsmutableattributedstring.
Uma Madhavi

@UmaMadhavi controlla questo link1 e link2 . Potrebbe essere utile!
Anurag Sharma

Si blocca se il carattere non è disponibile.
SafeFastExpressive

10

La risposta di Chris mi è stata di grande aiuto, quindi ho usato il suo approccio e mi sono trasformata in una funzione che posso riutilizzare. Questo mi permette di assegnare un colore a una sottostringa mentre dò al resto della stringa un altro colore.

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

per esempio se vuoi cambiare il carattere in NavBar:

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

6

Puoi usare questa estensione su cui testarlo

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

}

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

Ricevo un errore quando lo faccio. Penso che tu lo voglia senza .CGColor.
Bjorn Roche

@SarabjitSingh. come può questo è possibile per textview
Uma Madhavi

@UmaMadhavi ... Devi solo aggiungere self.textView.attributedText = myMutableString ..... Funzionerà ...
Sarabjit Singh

4

Il modo più semplice per creare etichette con uno stile diverso come colore, carattere ecc. È utilizzare la proprietà "Attribuito" in Attributes Inspector. Basta scegliere una parte del testo e modificarla come preferisci

inserisci qui la descrizione dell'immagine


1
Supponendo che tu non stia cambiando le corde in modo programmatico
Alejandro Cumpa

4

Basato sulle risposte prima di creare un'estensione di stringa

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

È possibile passare gli attributi per il testo al metodo

Chiama così

  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

Sono cambiato da questo in Swift 3

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

E questo in Swift 4.0

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

a Swift 4.1

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

Funziona bene


Questo sta cambiando l'intera stringa? Questo è il più leggibile per me, ma c'è un modo per cambiare solo parole specifiche all'interno della stringa come richiesto dall'OP.
Moondra

3

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

2

Per tutti coloro che cercano " Applicazione di un colore specifico a più parole nel testo ", possiamo farlo utilizzando 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
    }
}

Link di riferimento: https://gist.github.com/aquajach/4d9398b95a748fd37e88


È possibile utilizzare il codice nell'app Cocoa di MacOS? Ho provato a usarlo nel mio progetto di cacao, ma non c'è .attributedText in cocoa NSTextView.
CaOs433

2

Questo potrebbe essere un lavoro per te

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
Sebbene questo frammento di codice possa essere la soluzione, includere una spiegazione aiuta davvero a migliorare la qualità del tuo post. Ricorda che stai rispondendo alla domanda per i lettori in futuro e quelle persone potrebbero non conoscere i motivi del tuo suggerimento sul codice.
HMD

2

Con questa semplice funzione puoi assegnare il testo ed evidenziare la parola scelta.

Puoi anche cambiare UITextView in UILabel , ecc.

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

Per cambiare il colore del colore del carattere, seleziona prima attribuito anziché semplice come nell'immagine sottostante

È quindi necessario selezionare il testo nel campo attribuito e quindi selezionare il pulsante del colore sul lato destro degli allineamenti. Questo cambierà il colore.


1

Puoi usare questo metodo. Ho implementato questo metodo nella mia classe di utilità comune per accedere a livello globale.

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

Se stai usando Swift 3x e UITextView, forse NSForegroundColorAttributeName non funzionerà (non ha funzionato per me, indipendentemente dall'approccio che ho provato).

Quindi, dopo aver scavato un po 'ho trovato una soluzione.

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

Un modo semplicissimo per farlo.

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

Per maggiori dettagli fare clic qui: https://github.com/iOSTechHub/AttributedString


0

È necessario modificare i parametri della visualizzazione del testo, non i parametri della stringa attribuita

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

0

Si prega di controllare 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
}

}

usa EmailLbl.attributedText = EmailLbl.text! .markAsMandatoryField ()


0

Puoi usare come semplice estensione

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)

  
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.