zack_falcon
zack_falcon

Reputation: 4386

Is it possible to set a different colour for one character in a UILabel?

I've been working on a small project using Xcode. It uses a lot of labels, textfields, etc. I've finished with most of the layout, the constrains, and the forms, titles, etc. After which, the client announces that for all required fields, there should be a red asterisk next to the label.

Call me lazy, but I'd rather not go back to all of my forms, add in a lot of labels with asterisks on them, and re-do my auto-layout to accommodate the new labels.

So, is there a way to change the colour of a specific character (in this case, the asterisk) in a UILabel, while the rest of the text stays black?

Upvotes: 5

Views: 16508

Answers (7)

Naval Hasan
Naval Hasan

Reputation: 1520

Here is an extension for simply making mandatory labels by appending a red *

Swift 5

extension UILabel {
func makeTextMandatory() {
    let text = self.text ?? "" + " *"
    let range = (text as NSString).range(of: " *")
    let attributedString = NSMutableAttributedString(string:text)
    attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.red , range: range)
    self.attributedText = attributedString
  }
}

Usage :

dobLabel.makeTextMandatory()

Upvotes: 0

thevikasnayak
thevikasnayak

Reputation: 629

func updateAttributedStringWithCharacter(title : String, uilabel: UILabel) {
    let text = title + "*"
    let range = (text as NSString).range(of: "*")
    let attributedString = NSMutableAttributedString(string:text)
    attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.red , range: range)
    uilabel.attributedText = attributedString }

Upvotes: 2

Krunal
Krunal

Reputation: 79726

Swift 4
(Note: notation for attributed string key is changed in swift 4)

Here is an extension for NSMutableAttributedString, that add/set color on string/text.

extension NSMutableAttributedString {

    func setColor(color: UIColor, forText stringValue: String) {
        let range: NSRange = self.mutableString.range(of: stringValue, options: .caseInsensitive)
        self.addAttribute(NSAttributedStringKey.foregroundColor, value: color, range: range)
    }

}

Now, try above extension with UILabel and see result

let label = UILabel()
label.frame = CGRect(x: 40, y: 100, width: 280, height: 200)
let red = "red"
let blue = "blue"
let green = "green"
let stringValue = "\(red)\n\(blue)\n&\n\(green)"
label.textColor = UIColor.lightGray
label.numberOfLines = 0
let attributedString: NSMutableAttributedString = NSMutableAttributedString(string: stringValue)
attributedString.setColor(color: UIColor.red, forText: red)   // or use direct value for text "red"
attributedString.setColor(color: UIColor.blue, forText: blue)   // or use direct value for text "blue"
attributedString.setColor(color: UIColor.green, forText: green)   // or use direct value for text "green"
label.font = UIFont.systemFont(ofSize: 26)
label.attributedText = attributedString
self.view.addSubview(label)

Upvotes: 4

Wilson Muñoz
Wilson Muñoz

Reputation: 331

I know this is an old post, but i want to share my approach (which is based on the answer from dfri) i just made it a function for convenience.

func lastCharOnColor(label: UILabel, color: UIColor, length: Int) {

    //First we get the text.
    let string = label.text

    //Get number of characters on string and based on that get last character index.
    let characterCounter    = string?.characters.count
    let lastCharacterIndex  = characterCounter!-1

    //Set Range
    let range = NSRange(location: lastCharacterIndex, length: length)
    let attributedString = NSMutableAttributedString(string: string!, attributes: nil)

    //Set label
    attributedString.addAttribute(NSForegroundColorAttributeName, value: color, range: range)
    label.attributedText = attributedString

}

I use this function to just set the last character from a label to a certain color like this:

        lastCharOnColor(label: self.labelname, color: UIColor.red, length: 1)

Hope this helps anyone.

Upvotes: 1

tuledev
tuledev

Reputation: 10327

You can use NSMutableAttributedString. You can set specific range of your string with different color, font, size, ...

E.g:

 var range = NSRange(location:2,length:1) // specific location. This means "range" handle 1 character at location 2

 attributedString = NSMutableAttributedString(string: originalString, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 18.0)!])
 // here you change the character to red color
 attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: range)
 label.attributedText = attributedString

Ref: Use multiple font colors in a single label - Swift

You can change a lot of attribute of String. Ref from apple: https://developer.apple.com/library/prerelease/ios/documentation/Cocoa/Reference/Foundation/Classes/NSMutableAttributedString_Class/index.html

Upvotes: 11

dfrib
dfrib

Reputation: 73206

UILabel have an .attributedText property of type NSAttributedString.

Declaration

@NSCopying var attributedText: NSAttributedString?

You let your asterix * have a single .redColor() attribute (NSForegroundColorAttributeName), whereas the rest of the new label simply uses the same text as before, however also contained in an NSAttributedTextString.

An example follows below using a function to repeatedly update your existing labels to attributed strings prefixed with a red *:

class ViewController: UIViewController {

    @IBOutlet weak var myFirstLabel: UILabel!
    @IBOutlet weak var mySecondLabel: UILabel!

    let myPrefixCharacter = "*"
    let myPrefixColor = UIColor.redColor()    

    // ...

    override func viewDidLoad() {
        super.viewDidLoad()

        // ...

        /* update labels to attributed strings */
        updateLabelToAttributedString(myFirstLabel)
        updateLabelToAttributedString(mySecondLabel)
        // ...

    }

    func updateLabelToAttributedString(label: UILabel) {

        /* original label text as NSAttributedString, prefixed with " " */
        let attr = [ NSForegroundColorAttributeName: myPrefixColor ]
        let myNewLabelText = NSMutableAttributedString(string: myPrefixCharacter, attributes: attr)
        let myOrigLabelText = NSAttributedString(string: " " + (label.text ?? ""))

        /* set new label text as attributed string */
        myNewLabelText.appendAttributedString(myOrigLabelText)
        label.attributedText = myNewLabelText
    }

    // ...

}

enter image description here

Upvotes: 4

Ramesh_T
Ramesh_T

Reputation: 1261

let text = "Sample text *"
let range = (text as NSString).rangeOfString("*")
let attributedString = NSMutableAttributedString(string:text)
attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor() , range: range)

    //Apply to the label
    myLabel.attributedText = attributedString;

Upvotes: 9

Related Questions