Change UILabel's textColor in whole app using Swift
Asked Answered
M

4

11

Is there any way in Swift i can change my UILabel's text color property at once in whole app? I've tried using appeareance property but that doesn't work for UILabel textColor. Any way or any library that works on the same.

Municipal answered 5/1, 2019 at 11:14 Comment(1)
Using appearance only works for newly created labels, not existing labels.Yevetteyew
W
8

One way is using Color Set.

Start with creating new set in your xcassets catalog

enter image description here

... and name it how you want to

enter image description here

Then change your color to color that you need

enter image description here

Finally, set color of your label as this color from xcassets catalog

enter image description here enter image description here

... or programmatically

label.textColor = UIColor(named: "ColorForLabel")

Now when you need to change color of text, just change color of this Color Set

Whacky answered 5/1, 2019 at 11:45 Comment(5)
Nice solution but I think this a generic to define a color, also not exact solution for all UILabels. Because he have to set color again for each labelAvatar
Supported on iOS 11+.Burd
@arash look, there are elements like UIButton or UIBarButtonItem which has text color depenedent on property tintColor because you can set global tint and all "highlighted" elements will have this color. I don't think that is good solution to change color of all labels since labels can be use in various situations. Then, I think is good to use Color SetWhacky
and now you changed the question. As he said "change my UILabel's text color property at once in whole app" he wants to change all UILabels' text color in once.Avatar
@arash and this is exactly what my solution does. You just have to specify which labels and this seems better for me because of reasons which I wrote in comment above.Whacky
A
5

try this in your AppDelegate.swift inside didFinishLaunchingWithOptions function:

UILabel.appearance(whenContainedInInstancesOf: [UIView.self]).textColor = .red //or what color you want
Avatar answered 5/1, 2019 at 11:59 Comment(2)
Really good general solution. Wonder whether this could be setup to be overridden locally, as otherwise it can be too extreme.Himself
Just a follow up to my previous comment (if anyone reads it and shares my thought), I have posted an answer as well, which works almost the same, whilst allowing custom colours to be kept.Himself
H
4

I really liked Arash Etemad's solution, but found it quite extreme as it overrode ALL colours, even if some of them were customised. That's not great when working on an existing large project.

So I came up with this (Swift 5.2):

extension UILabel {

    override open func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)

        guard newSuperview != nil else {
            return
        }

        if #available(iOS 13.0, *) {
            if textColor == UIColor.label {
                textColor = .red
            }
        } else if textColor == UIColor.darkText {
            textColor = .red
        }
    }    
}

It uses the labels own lifecycle event to override default system font colour. With the appearance of dark mode in iOS 13, that can be identified as UIColor.label, whereas before it's UIColor.darkText.

This prevents a custom font colour from being overriden (unless your custom colour is the same as the default ?!? ), whilst not requiring to manually set font colour all over the project.

Himself answered 20/5, 2020 at 14:37 Comment(2)
Why you found my solution extreme? you set default color for UILabel and after that you can have some customized labels with different colors!Avatar
I work on a project developed by many people over many years. Some labels in this project default to system colour, others are custom. Your solution, applied in the AppDelegate didFinishLaunching, resulted in everything being changed to that colour, even though 95% had a custom colour already set. I suppose the way that colour is set could be updated, making it work, but then you'd convert 95% of the codebase, for the broken 5%. But I'd definitely prefer your solution on a new project, where there's not much legacy and it's a good pattern to use when it can be followed from start.Himself
C
1

Create a UILabel class and set the textColour in that class to your desired colour. And give this class to all the labels you are using in the app. If you want to change the colour of all labels during the session, say by button action, you can use NotificationCenter and Singleton for that purpose.

class LabelColor {
    static let shared = LabelColor()
    var color = UIColor.red
}

class ColoredLabel: UILabel {

    override func awakeFromNib() {
        super.awakeFromNib()
        textColor = LabelColor.shared.color
        NotificationCenter.default.addObserver(self, selector: #selector(self.changeColor(notification:)), name: Notification.Name(rawValue: "ChangeColor"), object: nil)
    }

    @objc func changeColor(notification: Notification) {
        let newColor = UIColor.blue
        textColor = newColor
        LabelColor.shared.color = newColor
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func changeColour(_ sender: UIButton) {
        NotificationCenter.default.post(name: Notification.Name("ChangeColor"), object: nil)
    }
}

StoryBoard

Chert answered 5/1, 2019 at 11:23 Comment(1)
Might be worth having a class level property that controls colour?Witness

© 2022 - 2024 — McMap. All rights reserved.