Search code examples
iosswiftuicolor

How to use hex color values


I am trying to use hex color values in Swift, instead of the few standard ones that UIColor allows you to use, but I have no idea how to do it.

Example: how would I use #ffffff as a color?


Solution

  • #ffffff are actually 3 color components in hexadecimal notation - red ff, green ff and blue ff. You can write hexadecimal notation in Swift using 0x prefix, e.g 0xFF

    To simplify the conversion, let's create an initializer that takes integer (0 - 255) values:

    extension UIColor {
       convenience init(red: Int, green: Int, blue: Int) {
           assert(red >= 0 && red <= 255, "Invalid red component")
           assert(green >= 0 && green <= 255, "Invalid green component")
           assert(blue >= 0 && blue <= 255, "Invalid blue component")
    
           self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: 1.0)
       }
    
       convenience init(rgb: Int) {
           self.init(
               red: (rgb >> 16) & 0xFF,
               green: (rgb >> 8) & 0xFF,
               blue: rgb & 0xFF
           )
       }
    }
    

    Usage:

    let color = UIColor(red: 0xFF, green: 0xFF, blue: 0xFF)
    let color2 = UIColor(rgb: 0xFFFFFF)
    

    How to get alpha?

    Depending on your use case, you can simply use the native UIColor.withAlphaComponent method, e.g.

    let semitransparentBlack = UIColor(rgb: 0x000000).withAlphaComponent(0.5)
    

    Or you can add an additional (optional) parameter to the above methods:

    convenience init(red: Int, green: Int, blue: Int, a: CGFloat = 1.0) {
        self.init(
            red: CGFloat(red) / 255.0,
            green: CGFloat(green) / 255.0,
            blue: CGFloat(blue) / 255.0,
            alpha: a
        )
    }
    
    convenience init(rgb: Int, a: CGFloat = 1.0) {
        self.init(
            red: (rgb >> 16) & 0xFF,
            green: (rgb >> 8) & 0xFF,
            blue: rgb & 0xFF,
            a: a
        )
    }
    

    (we cannot name the parameter alpha because of a name collision with the existing initializer).

    Called as:

    let color = UIColor(red: 0xFF, green: 0xFF, blue: 0xFF, a: 0.5)
    let color2 = UIColor(rgb: 0xFFFFFF, a: 0.5)
    

    To get the alpha as an integer 0-255, we can

    convenience init(red: Int, green: Int, blue: Int, a: Int = 0xFF) {
        self.init(
            red: CGFloat(red) / 255.0,
            green: CGFloat(green) / 255.0,
            blue: CGFloat(blue) / 255.0,
            alpha: CGFloat(a) / 255.0
        )
    }
    
    // let's suppose alpha is the first component (ARGB)
    convenience init(argb: Int) {
        self.init(
            red: (argb >> 16) & 0xFF,
            green: (argb >> 8) & 0xFF,
            blue: argb & 0xFF,
            a: (argb >> 24) & 0xFF
        )
    }
    

    Called as

    let color = UIColor(red: 0xFF, green: 0xFF, blue: 0xFF, a: 0xFF)
    let color2 = UIColor(argb: 0xFFFFFFFF)
    

    Or a combination of the previous methods. There is absolutely no need to use strings.