Cambia il colore della stringa con NSAttributedString?


147

Ho un dispositivo di scorrimento per un sondaggio che visualizza le seguenti stringhe in base al valore del dispositivo di scorrimento: "Very Bad, Bad, Okay, Good, Very Good".

Ecco il codice per il dispositivo di scorrimento:

- (IBAction) sliderValueChanged:(UISlider *)sender {
    scanLabel.text = [NSString stringWithFormat:@" %.f", [sender value]];
    NSArray *texts=[NSArray arrayWithObjects:@"Very Bad", @"Bad", @"Okay", @"Good", @"Very Good", @"Very Good", nil];
    NSInteger sliderValue=[sender value]; //make the slider value in given range integer one.
    self.scanLabel.text=[texts objectAtIndex:sliderValue];
}

Voglio che "Very Bad" sia rosso, "Bad" sia arancione, "Okay" sia giallo, "Good" e "Very Good" siano verdi.

Non capisco come usare NSAttributedStringper farlo.



Intendi un UISlider? Questo non ha un'etichetta. Quindi sostanzialmente si tratta di un UILabel con un colore del carattere? O vuoi che una parte del testo sia colorata?
Roger,


Usa questa libreria, è abbastanza semplice. github.com/iOSTechHub/AttributedString
Ashish Chauhan

Risposte:


196

Non è necessario per l'uso NSAttributedString. Tutto ciò che serve è un'etichetta semplice con il giusto textColor. Inoltre questa semplice soluzione funzionerà con tutte le versioni di iOS, non solo con iOS 6.

Ma se desideri inutilmente usare NSAttributedString, puoi fare qualcosa del genere:

UIColor *color = [UIColor redColor]; // select needed color
NSString *string = ... // the string to colorize
NSDictionary *attrs = @{ NSForegroundColorAttributeName : color };
NSAttributedString *attrStr = [[NSAttributedString alloc] initWithString:string attributes:attrs];
self.scanLabel.attributedText = attrStr;

4
Non capisco tutti i voti negativi. La mia risposta è molto più semplice rispetto all'utilizzo di una stringa attribuita. Non è necessario utilizzare l'OP NSAttributedStringper questa attività. Sarebbe una cosa se il testo dell'etichetta avesse bisogno di più attributi, ma non lo è. L'intera etichetta deve essere di un colore alla volta.
rmaddy,

@ RubénE.Marín Ma questo è il problema. L'OP ha erroneamente ritenuto che la soluzione richiedesse l'utilizzo NSAttributedString. Quindi è quello che hanno chiesto. La vera domanda avrebbe dovuto essere "Come impostare il colore dell'etichetta in base al suo valore" . Ho sottolineato che la soluzione non richiede NSAttributedStringe ha mostrato una risposta molto più semplice. E l'OP ha accettato accettando la mia risposta molto più semplice. Se l'OP volesse davveroNSAttributedString , non avrebbero accettato la mia risposta. Quindi non vi è alcun motivo per i voti negativi. Ho risposto alla vera domanda e l'OP ha accettato.
rmaddy,

24
In tal caso, avrei risolto la domanda con NSAttributedString e, successivamente, avrei indicato la soluzione più semplice ed efficiente per il caso particolare del PO. Le persone che arrivano a questa domanda potrebbero sentirsi frustrate dalla tua soluzione perché stanno cercando modi per cambiare il colore del testo su NSAttributedString (e questo spiegherebbe i tuoi voti negativi).
Ruben Marin,

15
Rubén ha ragione: sono venuto qui perché ho bisogno di impostare il colore in una stringa attribuita, perché sto costruendo una stringa attribuita composta con più colori e dimensioni del carattere. E l'informazione chiave di cui avevo bisogno era la NSForegroundColorAttributeNamechiave, che ho avuto difficoltà a trovare nei documenti di Apple.
Erik van der Neut,

5
Grazie per aver ancora risposto alla domanda !! anche se OP non ne aveva effettivamente bisogno. Tante volte google qualcosa, finisco su una domanda di overflow dello stack che è esattamente quello che sto cercando, solo per scoprire che il saggio che risponde alla domanda ha deciso che l'OP non aveva effettivamente bisogno di ciò che il titolo della domanda stava chiedendo e ha risposto a una domanda completamente diversa. Bene, le persone in futuro che provengono dai risultati della ricerca, di cui potrebbero esserci 1000 in contrapposizione al 1 ° PO, potrebbero effettivamente desiderare una soluzione alla domanda posta nel titolo del post. </rant>
danny l'

112

Usa qualcosa del genere (non compilatore verificato)

NSMutableAttributedString *string = [[NSMutableAttributedString alloc]initWithString:self.text.text];
NSRange range=[self.myLabel.text rangeOfString:texts[sliderValue]]; //myLabel is the outlet from where you will get the text, it can be same or different

NSArray *colors=@[[UIColor redColor],
                  [UIColor redColor],
                  [UIColor yellowColor],
                  [UIColor greenColor]
                 ];

[string addAttribute:NSForegroundColorAttributeName 
               value:colors[sliderValue] 
               range:range];           

[self.scanLabel setAttributedText:texts[sliderValue]];

Ehi Anoop, felice di rivederti! Ho bloccato il codice che hai fornito, ho sostituito self.text.text con self.scanLabel.text, ma visualizzo un errore in "word". Ho provato a sostituirlo con @ "Very Bad" senza fortuna.
Adam

Ho copiato la mia risposta da qui stackoverflow.com/questions/14231879/…
Anoop Vaidya,

Grazie Anoop, ma nessuna fortuna per me. - [__ NSCFString _ui_synthesizeAttributedSubstringFromRange: usingDefaultAttributes:]: selettore non riconosciuto inviato all'istanza 0x1f845af0 2013-01-11 16: 27: 34.939 yellaProto [7829: 907] *** Terminazione dell'app a causa di un'eccezione non rilevata 'NSInid': NSD ' _ui_synthesizeAttributedSubstringFromRange: usingDefaultAttributes:]: selettore non riconosciuto inviato all'istanza 0x1f845af0 '
Adam

Sto solo cercando di capire quali "testi"
Morkrom,

@Morkrom: se vedi il 2 ° commento in questa risposta, allora scoprirai: p
Anoop Vaidya

48

In Swift 4 :

// Custom color
let greenColor = UIColor(red: 10/255, green: 190/255, blue: 50/255, alpha: 1)
// create the attributed colour
let attributedStringColor = [NSAttributedStringKey.foregroundColor : greenColor];
// create the attributed string
let attributedString = NSAttributedString(string: "Hello World!", attributes: attributedStringColor)
// Set the label
label.attributedText = attributedString

In Swift 3 :

// Custom color
let greenColor = UIColor(red: 10/255, green: 190/255, blue: 50/255, alpha: 1)
// create the attributed color
let attributedStringColor : NSDictionary = [NSForegroundColorAttributeName : greenColor];
// create the attributed string
let attributedString = NSAttributedString(string: "Hello World!", attributes: attributedStringColor as? [String : AnyObject])
// Set the label
label.attributedText = attributedString 

Godere.


28

Per Swift 5:

var attributes = [NSAttributedString.Key: AnyObject]()
attributes[.foregroundColor] = UIColor.red

let attributedString = NSAttributedString(string: "Very Bad", attributes: attributes)

label.attributedText = attributedString

Per Swift 4:

var attributes = [NSAttributedStringKey: AnyObject]()
attributes[.foregroundColor] = UIColor.red

let attributedString = NSAttributedString(string: "Very Bad", attributes: attributes)

label.attributedText = attributedString

Per Swift 3:

var attributes = [String: AnyObject]()
attributes[NSForegroundColorAttributeName] = UIColor.red

let attributedString = NSAttributedString(string: "Very Bad", attributes: attributes)

label.attributedText = attributedString

7

Puoi creare NSAttributedString

NSDictionary *attributes = @{ NSForegroundColorAttributeName : [UIColor redColor] };
NSAttributedString *attrStr = [[NSAttributedString alloc] initWithString:@"My Color String" attributes:attrs];

O NSMutableAttributedStringper applicare attributi personalizzati con Ranges.

NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@%@", methodPrefix, method] attributes: @{ NSFontAttributeName : FONT_MYRIADPRO(48) }];
[attributedString addAttribute:NSFontAttributeName value:FONT_MYRIADPRO_SEMIBOLD(48) range:NSMakeRange(methodPrefix.length, method.length)];

Attributi disponibili: NSAttributedStringKey


AGGIORNARE:

Swift 5.1

let message: String = greeting + someMessage
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 2.0
    
// Note: UIFont(appFontFamily:ofSize:) is extended init.
let regularAttributes: [NSAttributedString.Key : Any] = [.font : UIFont(appFontFamily: .regular, ofSize: 15)!, .paragraphStyle : paragraphStyle]
let boldAttributes = [NSAttributedString.Key.font : UIFont(appFontFamily: .semiBold, ofSize: 15)!]

let mutableString = NSMutableAttributedString(string: message, attributes: regularAttributes)
mutableString.addAttributes(boldAttributes, range: NSMakeRange(0, greeting.count))

5

Con Swift 4, NSAttributedStringKeyha una proprietà statica chiamata foregroundColor. foregroundColorha la seguente dichiarazione:

static let foregroundColor: NSAttributedStringKey

Il valore di questo attributo è un UIColoroggetto. Utilizzare questo attributo per specificare il colore del testo durante il rendering. Se non si specifica questo attributo, il testo viene visualizzato in nero.

Il seguente codice Playground mostra come impostare il colore del testo di NSAttributedStringun'istanza con foregroundColor:

import UIKit

let string = "Some text"
let attributes = [NSAttributedStringKey.foregroundColor : UIColor.red]
let attributedString = NSAttributedString(string: string, attributes: attributes)

Il codice seguente mostra una possibile UIViewControllerimplementazione che si basa su NSAttributedStringper aggiornare il testo e il colore del testo di a UILabelda a UISlider:

import UIKit

enum Status: Int {
    case veryBad = 0, bad, okay, good, veryGood

    var display: (text: String, color: UIColor) {
        switch self {
        case .veryBad:  return ("Very bad", .red)
        case .bad:      return ("Bad", .orange)
        case .okay:     return ("Okay", .yellow)
        case .good:     return ("Good", .green)
        case .veryGood: return ("Very good", .blue)
        }
    }

    static let minimumValue = Status.veryBad.rawValue
    static let maximumValue = Status.veryGood.rawValue
}
final class ViewController: UIViewController {

    @IBOutlet weak var label: UILabel!
    @IBOutlet weak var slider: UISlider!
    var currentStatus: Status = Status.veryBad {
        didSet {
            // currentStatus is our model. Observe its changes to update our display
            updateDisplay()
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Prepare slider
        slider.minimumValue = Float(Status.minimumValue)
        slider.maximumValue = Float(Status.maximumValue)

        // Set display
        updateDisplay()
    }

    func updateDisplay() {
        let attributes = [NSAttributedStringKey.foregroundColor : currentStatus.display.color]
        let attributedString = NSAttributedString(string: currentStatus.display.text, attributes: attributes)
        label.attributedText = attributedString
        slider.value = Float(currentStatus.rawValue)
    }

    @IBAction func updateCurrentStatus(_ sender: UISlider) {
        let value = Int(sender.value.rounded())
        guard let status = Status(rawValue: value) else { fatalError("Could not get Status object from value") }
        currentStatus = status
    }

}

Si noti, tuttavia, che non si ha realmente bisogno di utilizzare NSAttributedStringper un tale esempio e può semplicemente fare affidamento su UILabel's texte textColorproprietà. Pertanto, è possibile sostituire l' updateDisplay()implementazione con il seguente codice:

func updateDisplay() {
    label.text = currentStatus.display.text
    label.textColor = currentStatus.display.color
    slider.value = Float(currentStatus.rawValue)
}

2

Aggiornamento per Swift 4.2

var attributes = [NSAttributedString.Key: AnyObject]()

attributes[.foregroundColor] = UIColor.blue

let attributedString = NSAttributedString(string: "Very Bad",
attributes: attributes)

label.attributedText = attributedString

1

Una fodera per Swift:

NSAttributedString(string: "Red Text", attributes: [.foregroundColor: UIColor.red])
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.