Search code examples
swiftuilabeluicolortextcolor

UILabel textColor Extension


I want to create an extension for UILabel, I want to modify the UILabel class to automatically check if the text value is positiv/negativ/cero and then set the Color automatically.

I want to activate it when I initialise UILabel in my code like this:

lazy var labelValue: UILabel! = {
        let lb = UILabel()
        lb.activateUpDown = true
        return lb
    }()

This is the extension I created:

extension UILabel {
    var activateUpDown: Bool {
        set {
            if activateUpDown == true {
               textColor = colorUpDown(value: text)
            }
        }
        get {
            return true
        }
    }

    func colorUpDown(value: String?) -> UIColor {
        let valueDouble = Double(value ?? "0") ?? 0
        var output:UIColor = .black
        if valueDouble < 0 {
            output = .red
        } else {
            if valueDouble > 0 {
                output = .green
            } else {
                output = .black
            }
        }
        return output
    }
}

When I set activateUpDown to true during my initialisation then it does not work.

If I put in updateConstraints it works but this is not where I want it.

override func updateConstraints() {
        if(shouldSetupConstraints) {
            shouldSetupConstraints = false
        }
        super.updateConstraints()
        labelValue.activateUpDown = true
    }

Is it possible to create the extension the way I want it or are my thoughts nonsense?

Edit: Basically what I want is I want to change the Setter of textColor, if activateUpDown is set to true and somebody sets textColor to a value. It checks if the value is positiv/negativ/zero.

I ended up doing a subclass of UILabel:

import UIKit

class CustomUILabel: UILabel {

    var activateUpDown = false


    var textValue: String? {
        willSet(newValue){
            text = newValue
            if activateUpDown == true {
            textColor = colorUpDown(value: newValue)
            }
        }
    }

    func colorUpDown(value: String?) -> UIColor {
        let valueDouble = Double(value ?? "0") ?? 0
        var output:UIColor = .black
        if valueDouble < 0 {
            output = .red
        } else {
            if valueDouble > 0 {
                output = .green
            } else {
                output = .black
            }
        }
        return output
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    /*
    // Only override draw() if you perform custom drawing.
    // An empty implementation adversely affects performance during animation.
    override func draw(_ rect: CGRect) {
        // Drawing code
    }
    */

}

Solution

  • Alternatively take advantage of the new Key-Value Observation skills of Swift 4, an extension of UILabel is not needed

    Create a property

    var textColorObservation : NSKeyValueObservation?
    

    and the observer

    textColorObservation = labelValue.observe(\.text, options: [.new])  { (label, change) in
        guard let text = change.newValue!, let doubleValue = Double(text) else { return }
        switch doubleValue {
           case ..<0: label.textColor = .red
           case 0: label.textColor = .black
           default: label.textColor = .green
        }
    }
    

    Side note:

    Don't declare labelValue as implicit unwrapped optional. You are clearly returning a non-optional object.