Last active
December 5, 2017 12:23
-
-
Save gotev/76df9006674762859626846cf171ff80 to your computer and use it in GitHub Desktop.
Color from Hex String in Swift 3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// UIColorFromRGB.swift | |
// | |
// | |
// Created by Alex Gotev on 21/11/16. | |
// | |
// | |
import Foundation | |
import UIKit | |
public extension UIColor { | |
public static func color(fromHexString: String, alpha:CGFloat? = 1.0) -> UIColor { | |
// Convert hex string to an integer | |
let hexint = Int(colorInteger(fromHexString: fromHexString)) | |
let red = CGFloat((hexint & 0xff0000) >> 16) / 255.0 | |
let green = CGFloat((hexint & 0xff00) >> 8) / 255.0 | |
let blue = CGFloat((hexint & 0xff) >> 0) / 255.0 | |
let alpha = alpha! | |
// Create color object, specifying alpha as well | |
let color = UIColor(red: red, green: green, blue: blue, alpha: alpha) | |
return color | |
} | |
private static func colorInteger(fromHexString: String) -> UInt32 { | |
var hexInt: UInt32 = 0 | |
// Create scanner | |
let scanner: Scanner = Scanner(string: fromHexString) | |
// Tell scanner to skip the # character | |
scanner.charactersToBeSkipped = CharacterSet(charactersIn: "#") | |
// Scan hex value | |
scanner.scanHexInt32(&hexInt) | |
return hexInt | |
} | |
var redValue: CGFloat{ | |
return cgColor.components! [0] | |
} | |
var greenValue: CGFloat{ | |
return cgColor.components! [1] | |
} | |
var blueValue: CGFloat{ | |
return cgColor.components! [2] | |
} | |
var alphaValue: CGFloat{ | |
return cgColor.components! [3] | |
} | |
// credits to @andreaantonioni for this addition | |
var isWhiteText: Bool { | |
let red = self.redValue * 255 | |
let green = self.greenValue * 255 | |
let blue = self.blueValue * 255 | |
// https://en.wikipedia.org/wiki/YIQ | |
// https://24ways.org/2010/calculating-color-contrast/ | |
let yiq = ((red * 299) + (green * 587) + (blue * 114)) / 1000 | |
return yiq < 192 | |
} | |
} |
you can also make isWhiteText
a stored property of UIColor
extension UIColor {
var isWhiteText: Bool {
let red = self.redValue * 255
let green = self.greenValue * 255
let blue = self.blueValue * 255
// https://en.wikipedia.org/wiki/YIQ
// https://24ways.org/2010/calculating-color-contrast/
let yiq = ((red * 299) + (green * 587) + (blue * 114)) / 1000
return yiq < 192
}
}
@andreaantonioni added your addition to the UIColor
extension
The previous version doesn't support non-RGB colors (for example UIColor.black
or UIColor.white
) but with this fix it works
var isWhiteText: Bool {
// non-RGB color
if cgColor.numberOfComponents == 2 {
return 0.0...0.5 ~= cgColor.components!.first! ? true : false
}
let red = self.redValue * 255
let green = self.greenValue * 255
let blue = self.blueValue * 255
// https://en.wikipedia.org/wiki/YIQ
// https://24ways.org/2010/calculating-color-contrast/
let yiq = ((red * 299) + (green * 587) + (blue * 114)) / 1000
return yiq < 192
}
how do I use isWhiteText? It looks to be a get only property.
The Swift 4 version looks like this:
extension UIColor {
convenience init(hexString: String, alpha: CGFloat = 1.0) {
let hexString: String = hexString.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
let scanner = Scanner(string: hexString)
if (hexString.hasPrefix("#")) {
scanner.scanLocation = 1
}
var color: UInt32 = 0
scanner.scanHexInt32(&color)
let mask = 0x000000FF
let r = Int(color >> 16) & mask
let g = Int(color >> 8) & mask
let b = Int(color) & mask
let red = CGFloat(r) / 255.0
let green = CGFloat(g) / 255.0
let blue = CGFloat(b) / 255.0
self.init(red:red, green:green, blue:blue, alpha:alpha)
}
func toHexString() -> String {
var r:CGFloat = 0
var g:CGFloat = 0
var b:CGFloat = 0
var a:CGFloat = 0
getRed(&r, green: &g, blue: &b, alpha: &a)
let rgb:Int = (Int)(r*255)<<16 | (Int)(g*255)<<8 | (Int)(b*255)<<0
return String(format:"#%06x", rgb)
}
}
It crashes on some hex strings on 32 bit devices... "Not enough bits to represent a signed value"
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage:
This extension also eases more complex functions, such as determining if the text color should be black or white, given a background color: