【问题标题】:'scanHexInt32' was deprecated in iOS 13.0“scanHexInt32”在 iOS 13.0 中已弃用
【发布时间】:2020-01-12 04:41:36
【问题描述】:

在 iOS 13 (Swift 5+) 中 scanHexInt32 的替代品是什么?

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)
        )
    }
}

参考:快照

【问题讨论】:

  • 你解决了这个警告吗?
  • 只需使用 UInt64。看看here
  • 换行:Scanner(string: cString).scanHexInt64(&rgbValue)
  • 感谢 Rohit,我试过了,但收到了这个警告 - “无法将类型 '(UnsafeMutablePointer?) -> Bool' 的值转换为预期的参数类型 'UInt32'”
  • 你需要为scanner.isAtEnd添加一个检查

标签: swift hex ios13 uicolor


【解决方案1】:

更新为使用UInt64scanHexInt64

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)
}

【讨论】:

    【解决方案2】:

    看起来苹果正在从他们的 64 位操作系统中逐步淘汰 Int32。尝试将您的代码转换为使用 Int64。

    @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"
    

    【讨论】:

      【解决方案3】:

      还有另一个实例方法可用

      scanInt32(representation:)
      

      声明:

      func scanInt32(representation: Scanner.NumberRepresentation = .decimal) -> Int32?
      

      这里你必须传递枚举.hexadecimal

      我希望它会返回相同的结果。结果将是可选的。

      【讨论】:

      • 我同意。你会注意到scanInt32(representation:) 是对 Scanner 的更新,它取消了 C 风格的 inout 参数并返回一个可选的,这是 Swifty 的方式。这显然是为了替代。编译器的弃用通知应该提到这一点。
      【解决方案4】:

      试试这个扩展 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)
          }
      }
      

      【讨论】:

        【解决方案5】:

        我正在使用这个 uicolor 扩展.. 请找到下面的代码

        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)
            )
        } }
        

        【讨论】:

        • 这不考虑RGBA HEX
        【解决方案6】:

        斯威夫特 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)
            }
          }
        }
        

        【讨论】:

          【解决方案7】:

          这结合了几个答案,提供 UInt64 和字符串表示。它还删除了 Color 不需要的“convenience”关键字,因为它是一个结构(而 UIColor 需要它,因为它是一个类)。最后,它使用 Double 而不是 CGFloat - 这也是 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)
                  }
              }
          

          【讨论】:

            猜你喜欢
            • 2020-09-07
            • 1970-01-01
            • 2019-11-29
            • 2020-03-04
            • 2020-07-26
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多