Created
July 20, 2014 20:04
-
-
Save rpomeroy/c0bf58a2c62f34fdad8d to your computer and use it in GitHub Desktop.
NSColor from hex or hexString
This file contains 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
// Paste in playground | |
// Handy NSColor and String extensions | |
import Cocoa | |
extension String { | |
func conformsTo(pattern: String) -> Bool { | |
let pattern = NSPredicate(format:"SELF MATCHES %@", pattern) | |
return pattern.evaluateWithObject(self) | |
} | |
} | |
extension NSColor { | |
class func fromHex(hex: Int, alpha: Float) -> NSColor { | |
let red = CGFloat((hex & 0xFF0000) >> 16) / 255.0 | |
let green = CGFloat((hex & 0xFF00) >> 8) / 255.0 | |
let blue = CGFloat((hex & 0xFF)) / 255.0 | |
return NSColor(calibratedRed: red, green: green, blue: blue, alpha: 1.0) | |
} | |
class func fromHexString(hex: String, alpha: Float) -> NSColor? { | |
// Handle two types of literals: 0x and # prefixed | |
var cleanedString = "" | |
if hex.hasPrefix("0x") { | |
cleanedString = hex.substringFromIndex(2) | |
} else if hex.hasPrefix("#") { | |
cleanedString = hex.substringFromIndex(1) | |
} | |
// Ensure it only contains valid hex characters 0 | |
let validHexPattern = "[a-fA-F0-9]+" | |
if cleanedString.conformsTo(validHexPattern) { | |
var theInt: UInt32 = 0 | |
let scanner = NSScanner.scannerWithString(cleanedString) | |
scanner.scanHexInt(&theInt) | |
let red = CGFloat((theInt & 0xFF0000) >> 16) / 255.0 | |
let green = CGFloat((theInt & 0xFF00) >> 8) / 255.0 | |
let blue = CGFloat((theInt & 0xFF)) / 255.0 | |
return NSColor(calibratedRed: red, green: green, blue: blue, alpha: 1.0) | |
} else { | |
return Optional.None | |
} | |
} | |
} | |
// Tests | |
let hex: Int = 0xa1bbca | |
let hexString: String = "#a1bbca" | |
let hexStringAlt = "0xa1bbca" | |
let hexColor = NSColor.fromHex(hex, alpha: 1.0) | |
let hexColorFromString = NSColor.fromHexString(hexString, alpha: 1.0)! | |
let hexColorFromStringAlt = NSColor.fromHexString(hexStringAlt, alpha: 1.0)! | |
Thanks @ozanm this is the fix for "Fatal Error: String index out of bounds" in Swift 5:
import Cocoa
extension String {
func conformsTo(_ pattern: String) -> Bool {
return NSPredicate(format:"SELF MATCHES %@", pattern).evaluate(with: self)
}
}
extension NSColor {
convenience init(hex: Int, alpha: Float) {
self.init(
calibratedRed: CGFloat((hex & 0xFF0000) >> 16) / 255.0,
green: CGFloat((hex & 0xFF00) >> 8) / 255.0,
blue: CGFloat((hex & 0xFF)) / 255.0,
alpha: 1.0
)
}
convenience init(hex: String, alpha: Float) {
// Handle two types of literals: 0x and # prefixed
var cleanedString = ""
if hex.hasPrefix("0x") {
cleanedString = String(hex[hex.index(cleanedString.startIndex, offsetBy: 2)..<hex.endIndex])
} else if hex.hasPrefix("#") {
cleanedString = String(hex[hex.index(cleanedString.startIndex, offsetBy: 1)..<hex.endIndex])
}
// Ensure it only contains valid hex characters 0
let validHexPattern = "[a-fA-F0-9]+"
if cleanedString.conformsTo(validHexPattern) {
var value: UInt32 = 0
Scanner(string: cleanedString).scanHexInt32(&value)
self.init(hex: Int(value), alpha: 1)
} else {
fatalError("Unable to parse color?")
}
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you for creating this, it really saved me a lot of time. If one were to need it, the following is the Swift 5 version of your code.