'scanHexInt32' was deprecated in iOS 13.0
SwiftHexIos13UicolorSwift Problem Overview
What is alternate of scanHexInt32
in iOS 13 (Swift 5+)?
extension UIColor {
//--------------------------------------------
class func hexColor(hex:String) -> UIColor {
var cString:String = hex.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).uppercased()
if (cString.hasPrefix("#")) {
cString = String(cString[cString.index(cString.startIndex, offsetBy: 1)...])
}
if (cString.count != 6) {
return UIColor.gray
}
var rgbValue:UInt32 = 0
// warning in this line - 'scanHexInt32' was deprecated in iOS 13.0
Scanner(string: cString).scanHexInt32(&rgbValue)
return UIColor(
red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
alpha: CGFloat(1.0)
)
}
}
Ref: Snapshot
Swift Solutions
Solution 1 - Swift
Update to use UInt64
and scanHexInt64
:
convenience init(hex: String, alpha: CGFloat = 1.0) {
var hexFormatted: String = hex.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).uppercased()
if hexFormatted.hasPrefix("#") {
hexFormatted = String(hexFormatted.dropFirst())
}
assert(hexFormatted.count == 6, "Invalid hex code used.")
var rgbValue: UInt64 = 0
Scanner(string: hexFormatted).scanHexInt64(&rgbValue)
self.init(red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
alpha: alpha)
}
Solution 2 - Swift
Looks like apple is phasing out Int32 from their 64bit OSs. Try convert your code to use Int64 instead.
@available(iOS, introduced: 2.0, deprecated: 13.0)
open func scanHexInt32(_ result: UnsafeMutablePointer<UInt32>?) -> Bool // Optionally prefixed with "0x" or "0X"
@available(iOS 2.0, *)
open func scanHexInt64(_ result: UnsafeMutablePointer<UInt64>?) -> Bool // Optionally prefixed with "0x" or "0X"
Solution 3 - Swift
There is another Instance Method available
scanInt32(representation:)
Declaration:
func scanInt32(representation: Scanner.NumberRepresentation = .decimal) -> Int32?
Here you have to pass enum .hexadecimal.
I hope it will return same result. Result will be optional.
Solution 4 - Swift
Try this extension swiftui :
extension Color {
init(hex: String) {
let scanner = Scanner(string: hex)
scanner.currentIndex = scanner.string.startIndex
var rgbValue: UInt64 = 0
scanner.scanHexInt64(&rgbValue)
let r = (rgbValue & 0xff0000) >> 16
let g = (rgbValue & 0xff00) >> 8
let b = rgbValue & 0xff
self.init(red: Double(r) / 0xff, green: Double(g) / 0xff, blue: Double(b) / 0xff)
}
}
Solution 5 - Swift
I am using this uicolor extension.. please find the below code
extension UIColor {
class func hexColor(hex:String) -> UIColor {
var cString:String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
if (cString.hasPrefix("#")) {
cString.remove(at: cString.startIndex)
}
if ((cString.count) != 6) {
return UIColor.gray
}
var rgbValue:UInt64 = 0
Scanner(string: cString).scanHexInt64(&rgbValue)
return UIColor(
red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0,
green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0,
blue: CGFloat(rgbValue & 0x0000FF) / 255.0,
alpha: CGFloat(1.0)
)
} }
Solution 6 - Swift
Swift 5
extension String {
var color: UIColor {
let hex = trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
if #available(iOS 13, *) {
guard let int = Scanner(string: hex).scanInt32(representation: .hexadecimal) else { return #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0) }
let a, r, g, b: Int32
switch hex.count {
case 3: (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17) // RGB (12-bit)
case 6: (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF) // RGB (24-bit)
case 8: (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF) // ARGB (32-bit)
default: (a, r, g, b) = (255, 0, 0, 0)
}
return UIColor(red: CGFloat(r) / 255.0, green: CGFloat(g) / 255.0, blue: CGFloat(b) / 255.0, alpha: CGFloat(a) / 255.0)
} else {
var int = UInt32()
Scanner(string: hex).scanHexInt32(&int)
let a, r, g, b: UInt32
switch hex.count {
case 3: (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17) // RGB (12-bit)
case 6: (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF) // RGB (24-bit)
case 8: (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF) // ARGB (32-bit)
default: (a, r, g, b) = (255, 0, 0, 0)
}
return UIColor(red: CGFloat(r) / 255.0, green: CGFloat(g) / 255.0, blue: CGFloat(b) / 255.0, alpha: CGFloat(a) / 255.0)
}
}
}
Solution 7 - Swift
This combines a couple of the answers, providing both UInt64 and String representations. It also removes the "convenience" keyword which is unnecessary for Color because it is a struct (whereas it was needed for UIColor since it is a class). Lastly, it uses Double instead of CGFloat - again, necessary for Color.
extension Color
{
init(_ hex: UInt64, opacity: Double = 1.0)
{
let red = Double((hex & 0xff0000) >> 16) / 255.0
let green = Double((hex & 0xff00) >> 8) / 255.0
let blue = Double((hex & 0xff) >> 0) / 255.0
self.init(.sRGB, red: red, green: green, blue: blue, opacity: opacity)
}
init(hex: String, opacity: Double = 1.0)
{
// convert the String into an UInt64 and then convert into Color
var hexFormatted: String = hex.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines).uppercased()
if hexFormatted.hasPrefix("#")
{
hexFormatted = String(hexFormatted.dropFirst())
}
assert(hexFormatted.count == 6, "Invalid hex code used.")
var rgbValue: UInt64 = 0
Scanner(string: hexFormatted).scanHexInt64(&rgbValue)
self.init(rgbValue, opacity: opacity)
}
}