Changer la couleur de la chaîne avec NSAttributedString?

147

J'ai un curseur pour une enquête qui affiche les chaînes suivantes en fonction de la valeur du curseur: "Très mauvais, mauvais, correct, bon, très bon".

Voici le code du curseur:

- (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];
}

Je veux que «Very Bad» soit rouge, «Bad» soit orange, «Okay» soit jaune, «Good» et «Very Good» soit vert.

Je ne comprends pas comment utiliser NSAttributedStringpour y parvenir.

Adam
la source
Vous voulez dire un UISlider? Cela n'a pas d'étiquette. Donc, fondamentalement, il s'agit d'un UILabel avec une couleur de police? Ou voulez-vous qu'une partie du texte soit colorée?
Roger
2
duplication possible de Comment utilisez-vous NSAttributedString?
John Parker
Utilisez cette bibliothèque, c'est assez simple. github.com/iOSTechHub/AttributedString
Ashish Chauhan

Réponses:

196

Il n'est pas nécessaire d'utiliser NSAttributedString. Tout ce dont vous avez besoin est une simple étiquette avec le bon textColor. De plus, cette solution simple fonctionnera avec toutes les versions d'iOS, pas seulement iOS 6.

Mais si vous souhaitez utiliser inutilement NSAttributedString, vous pouvez faire quelque chose comme ceci:

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;
rmaddy
la source
4
Je ne comprends pas tous les votes négatifs. Ma réponse est beaucoup plus simple que d'utiliser une chaîne attribuée. L'OP n'a pas besoin d'être utilisé NSAttributedStringpour cette tâche. Ce serait une chose si le texte de l'étiquette avait besoin de plusieurs attributs, mais ce n'est pas le cas. L'étiquette entière doit être une couleur à la fois.
rmaddy
@ RubénE.Marín Mais c'est le problème. L'OP a pensé à tort que la solution nécessitait l'utilisation NSAttributedString. C'est donc ce qu'ils ont demandé. La vraie question aurait dû être "Comment définir la couleur de l'étiquette en fonction de sa valeur" . J'ai souligné que la solution ne nécessite pas NSAttributedStringet a montré une réponse beaucoup plus simple. Et le PO a accepté en acceptant ma réponse beaucoup plus simple. Si le PO le voulait vraimentNSAttributedString , il n'aurait pas accepté ma réponse. Il n'y a donc aucune raison pour les votes négatifs. J'ai répondu à la vraie question et le PO a accepté.
rmaddy
24
Dans ce cas, j'aurais résolu la question avec NSAttributedString et, après cela, j'aurais indiqué votre solution plus simple et plus efficace pour le cas particulier de l'OP. Les personnes qui viennent à cette question peuvent se sentir frustrées par votre solution parce qu'elles recherchent des moyens de changer la couleur du texte sur NSAttributedString (et cela expliquerait vos votes négatifs).
Ruben Marin
15
Rubén a raison: je suis venu ici parce que je dois définir la couleur dans une chaîne attribuée, parce que je construis une chaîne attribuée composée avec plusieurs couleurs et tailles de police. Et l'information clé dont j'avais besoin était la NSForegroundColorAttributeNameclé, que j'ai eu du mal à trouver dans la documentation Apple.
Erik van der Neut
5
Merci d'avoir encore répondu à la question !! même si OP n'en avait pas réellement besoin. Tant de fois, je cherche quelque chose sur Google, je me retrouve sur une question de débordement de pile, c'est exactement ce que je recherche, seulement pour constater que le sage qui a répondu à la question a décidé que le PO n'avait pas vraiment besoin de ce que le titre de la question demandait et a répondu à une question complètement différente. Eh bien, à l'avenir, les personnes provenant des résultats de recherche, dont il pourrait y avoir des milliers par opposition au 1 OP, pourraient en fait vouloir une solution à la question posée dans le titre du message. </rant>
danny
112

Utilisez quelque chose comme ça (non vérifié par le compilateur)

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]];
Anoop Vaidya
la source
Hey Anoop, content de te revoir! J'ai trié le code que vous avez fourni, j'ai remplacé self.text.text par self.scanLabel.text, mais j'obtiens une erreur au niveau de "word". J'ai essayé de le remplacer par @ "Very Bad" sans succès.
Adam
J'ai copié ma réponse d'ici stackoverflow.com/questions/14231879/…
Anoop Vaidya
Merci Anoop, mais pas de chance pour moi. - [__ NSCFString _ui_synthesizeAttributedSubstringFromRange: usingDefaultAttributes:]: sélecteur non reconnu envoyé à l'instance 0x1f845af0 11/01/2013 16: 27: 34.939 yellaProto [7829: 907] *** Arrêt de l'application en raison d'une exception non interceptée 'NSFSInvalid', __gument'Exception _ui_synthesizeAttributedSubstringFromRange: usingDefaultAttributes:]: sélecteur non reconnu envoyé à l'instance 0x1f845af0 '
Adam
Essayez juste de comprendre otu quels "textes"
Morkrom
@Morkrom: si vous voyez le deuxième commentaire dans cette réponse, vous apprendrez à connaître: p
Anoop Vaidya
48

Dans 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

Dans 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 

Prendre plaisir.

Développeur d'applications
la source
28

Pour Swift 5:

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

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

label.attributedText = attributedString

Pour Swift 4:

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

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

label.attributedText = attributedString

Pour Swift 3:

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

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

label.attributedText = attributedString
pableiros
la source
7

Vous pouvez créer NSAttributedString

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

OU NSMutableAttributedStringpour appliquer des attributs personnalisés avec des plages.

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

Attributs disponibles: NSAttributedStringKey


METTRE À JOUR:

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))
Lal Krishna
la source
5

Avec Swift 4, NSAttributedStringKeya une propriété statique appelée foregroundColor. foregroundColora la déclaration suivante:

static let foregroundColor: NSAttributedStringKey

La valeur de cet attribut est un UIColorobjet. Utilisez cet attribut pour spécifier la couleur du texte lors du rendu. Si vous ne spécifiez pas cet attribut, le texte est rendu en noir.

Le code Playground suivant montre comment définir la couleur du texte d'une NSAttributedStringinstance avec foregroundColor:

import UIKit

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

Le code ci-dessous montre une UIViewControllerimplémentation possible qui s'appuie sur NSAttributedStringpour mettre à jour le texte et la couleur du texte d'un à UILabelpartir d'un 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
    }

}

Notez toutefois que vous n'avez pas vraiment besoin d'utiliser NSAttributedStringun tel exemple et peut simplement compter sur UILabell » textet textColorpropriétés. Par conséquent, vous pouvez remplacer votre updateDisplay()implémentation par le code suivant:

func updateDisplay() {
    label.text = currentStatus.display.text
    label.textColor = currentStatus.display.color
    slider.value = Float(currentStatus.rawValue)
}
Imanou Petit
la source
2

Mise à jour pour Swift 4.2

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

attributes[.foregroundColor] = UIColor.blue

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

label.attributedText = attributedString
Mithra Singam
la source
1

Une doublure pour Swift:

NSAttributedString(string: "Red Text", attributes: [.foregroundColor: UIColor.red])
Fedotchenco Denis
la source