[ios] Change string color with NSAttributedString?

I have a slider for a survey that display the following strings based on the value of the slider: "Very Bad, Bad, Okay, Good, Very Good".

Here is the code for the slider:

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

I want "Very Bad" to be red, "Bad" to be orange, "Okay" to be yellow, "Good" and "Very Good" to be green.

I don't understand how to use NSAttributedString to get this done.

This question is related to ios cocoa-touch nsattributedstring

The answer is


There is no need for using NSAttributedString. All you need is a simple label with the proper textColor. Plus this simple solution will work with all versions of iOS, not just iOS 6.

But if you needlessly wish to use NSAttributedString, you can do something like this:

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;

You can create NSAttributedString

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

OR NSMutableAttributedString to apply custom attributes with 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)];

Available Attributes: NSAttributedStringKey


UPDATE:

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

With Swift 4, NSAttributedStringKey has a static property called foregroundColor. foregroundColor has the following declaration:

static let foregroundColor: NSAttributedStringKey

The value of this attribute is a UIColor object. Use this attribute to specify the color of the text during rendering. If you do not specify this attribute, the text is rendered in black.

The following Playground code shows how to set the text color of an NSAttributedString instance with foregroundColor:

import UIKit

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

The code below shows a possible UIViewController implementation that relies on NSAttributedString in order to update the text and text color of a UILabel from 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
    }

}

Note however that you don't really need to use NSAttributedString for such an example and can simply rely on UILabel's text and textColor properties. Therefore, you can replace your updateDisplay() implementation with the following code:

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

For Swift 5:

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

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

label.attributedText = attributedString

For Swift 4:

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

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

label.attributedText = attributedString

For Swift 3:

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

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

label.attributedText = attributedString

Update for Swift 4.2

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

attributes[.foregroundColor] = UIColor.blue

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

label.attributedText = attributedString

Use something like this (Not compiler checked)

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

One liner for Swift:

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

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 

Enjoy.


Examples related to ios

Adding a UISegmentedControl to UITableView Crop image to specified size and picture location Undefined Symbols error when integrating Apptentive iOS SDK via Cocoapods Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Autoresize View When SubViews are Added Warp \ bend effect on a UIView? Speech input for visually impaired users without the need to tap the screen make UITableViewCell selectable only while editing Xcode 12, building for iOS Simulator, but linking in object file built for iOS, for architecture arm64

Examples related to cocoa-touch

Include of non-modular header inside framework module Move textfield when keyboard appears swift Create space at the beginning of a UITextField Navigation bar with UIImage for title Generate a UUID on iOS from Swift How do I write a custom init for a UIView subclass in Swift? creating custom tableview cells in swift How would I create a UIAlertView in Swift? Get current NSDate in timestamp format How do you add an in-app purchase to an iOS application?

Examples related to nsattributedstring

Swift: Display HTML data in a label or textView How to underline a UILabel in swift? How do I make an attributed string using Swift? How can I make a clickable link in an NSAttributedString? Change string color with NSAttributedString? boundingRectWithSize for NSAttributedString returning wrong size NSAttributedString add text alignment Convert HTML to NSAttributedString in iOS Bold & Non-Bold Text In A Single UILabel? How do you use NSAttributedString?