Swift 4 : >> operator is unavailable Looking for replacement operator for converting HexColor to UIColor in Swift 4.0 :
Here is sample code for earlier code version in Swift 3.0.
public extension UIColor {
convenience init(hex: String) {
var red: CGFloat = 0.0
var green: CGFloat = 0.0
var blue: CGFloat = 0.0
var alpha: CGFloat = 1.0
if hex.hasPrefix("#") {
let index = hex.characters.index(hex.startIndex, offsetBy: 1)
let hex = hex.substring(from: index)
let scanner = Scanner(string: hex)
var hexValue: CUnsignedLongLong = 0
if scanner.scanHexInt64(&hexValue) {
switch (hex.characters.count) {
case 3:
red = CGFloat((hexValue & 0xF00) >> 8) / 15.0
green = CGFloat((hexValue & 0x0F0) >> 4) / 15.0
blue = CGFloat(hexValue & 0x00F) / 15.0
case 4:
red = CGFloat((hexValue & 0xF000) >> 12) / 15.0
green = CGFloat((hexValue & 0x0F00) >> 8) / 15.0
blue = CGFloat((hexValue & 0x00F0) >> 4) / 15.0
alpha = CGFloat(hexValue & 0x000F) / 15.0
case 6:
red = CGFloat((hexValue & 0xFF0000) >> 16) / 255.0
green = CGFloat((hexValue & 0x00FF00) >> 8) / 255.0
blue = CGFloat(hexValue & 0x0000FF) / 255.0
case 8:
red = CGFloat((hexValue & 0xFF000000) >> 24) / 255.0
green = CGFloat((hexValue & 0x00FF0000) >> 16) / 255.0
blue = CGFloat((hexValue & 0x0000FF00) >> 8) / 255.0
alpha = CGFloat(hexValue & 0x000000FF) / 255.0
default:
print("Invalid RGB string, number of characters after '#' should be either 3, 4, 6 or 8", terminator: "")
}
} else {
// print("Scan hex error")
}
} else {
// print("Invalid RGB string, missing '#' as prefix", terminator: "")
}
self.init(red:red, green:green, blue:blue, alpha:alpha)
}
}
Thanks in advance.
This code has no problems with >>
operator in Swift 4. The only issue is the string handling. I might replace
let index = hex.characters.index(hex.startIndex, offsetBy: 1)
let hex = hex.substring(from: index)
with
let index = hex.index(hex.startIndex, offsetBy: 1)
let hex = String(hex[index...])
Personally, I'd make a few other changes to that routine:
I'd make it failable initializer (e.g. init?(...)
returning an optional). Right now the calling code has no way of knowing if the conversion to UIColor
failed.
I'd simplify the above string handling, reducing it to:
let hex = hex.replacingOccurrences(of: "^#", with: "", options: .regularExpression)
Not only does that reduce it to a single line which removes any leading #
present, but it also means that this code will now also work if you pass it a hex string that doesn't have the leading #
.
I'd use UInt64(_:radix:)
instead of the scanner. It's just a little simpler.
Thus:
public extension UIColor {
convenience init?(hex: String) {
var red: CGFloat = 0.0
var green: CGFloat = 0.0
var blue: CGFloat = 0.0
var alpha: CGFloat = 1.0
let hex = hex.replacingOccurrences(of: "^#", with: "", options: .regularExpression)
guard let hexValue = UInt64(hex, radix: 16) else {
print("invalid hex string")
return nil
}
switch (hex.count) {
case 3:
red = CGFloat((hexValue & 0xF00) >> 8) / 15.0
green = CGFloat((hexValue & 0x0F0) >> 4) / 15.0
blue = CGFloat(hexValue & 0x00F) / 15.0
case 4:
red = CGFloat((hexValue & 0xF000) >> 12) / 15.0
green = CGFloat((hexValue & 0x0F00) >> 8) / 15.0
blue = CGFloat((hexValue & 0x00F0) >> 4) / 15.0
alpha = CGFloat(hexValue & 0x000F) / 15.0
case 6:
red = CGFloat((hexValue & 0xFF0000) >> 16) / 255.0
green = CGFloat((hexValue & 0x00FF00) >> 8) / 255.0
blue = CGFloat(hexValue & 0x0000FF) / 255.0
case 8:
red = CGFloat((hexValue & 0xFF000000) >> 24) / 255.0
green = CGFloat((hexValue & 0x00FF0000) >> 16) / 255.0
blue = CGFloat((hexValue & 0x0000FF00) >> 8) / 255.0
alpha = CGFloat(hexValue & 0x000000FF) / 255.0
default:
print("Invalid RGB string, number of characters after '#' should be either 3, 4, 6 or 8", terminator: "")
return nil
}
self.init(red: red, green: green, blue: blue, alpha: alpha)
}
}
User contributions licensed under CC BY-SA 3.0