You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS开发中带透明度的8位Hex颜色码解析结果不符合预期

问题根因

8位带透明度的Hex色值存在两种通用通道排列规范,当前代码的解析顺序和传入色值遵循的顺序不匹配,四个颜色分量全部错位:

  • 传入的色值#80478295遵循AARRGGBB排列规范:前2位为Alpha透明度通道,后续6位依次为R、G、B颜色通道,对应分量为A=0x80(对应50%透明度)、R=0x47、G=0x82、B=0x95,和预期RGBA值完全吻合
  • 当前代码的解析逻辑按RRGGBBAA排列实现:将前2位解析为R通道,后续依次解析G、B通道,最后2位解析为Alpha通道,直接导致原本属于Alpha通道的0x80被读为R值,原R值0x47被读为G值,原G值0x82被读为B值,原B值0x95被读为Alpha值,和实际打印出的错误分量完全匹配。
修复方案

调整8位Hex的通道取值位运算逻辑,匹配AARRGGBB排列规则,同时可兼容6位无透明度的常规Hex色值,修正后代码如下:

public convenience init?(hex: String) {
    let r, g, b, a: CGFloat
    
    if hex.hasPrefix("#") {
        let start = hex.index(hex.startIndex, offsetBy: 1)
        let hexColor = String(hex[start...])
        
        var hexNumber: UInt64 = 0
        guard Scanner(string: hexColor).scanHexInt64(&hexNumber) else {
            return nil
        }
        
        if hexColor.count == 8 {
            // 8位AARRGGBB格式解析
            a = CGFloat((hexNumber & 0xff000000) >> 24) / 255
            r = CGFloat((hexNumber & 0x00ff0000) >> 16) / 255
            g = CGFloat((hexNumber & 0x0000ff00) >> 8) / 255
            b = CGFloat(hexNumber & 0x000000ff) / 255
            self.init(red: r, green: g, blue: b, alpha: a)
            return
        } else if hexColor.count == 6 {
            // 兼容6位RRGGBB无透明度格式,默认不透明
            r = CGFloat((hexNumber & 0xff0000) >> 16) / 255
            g = CGFloat((hexNumber & 0x00ff00) >> 8) / 255
            b = CGFloat(hexNumber & 0x0000ff) / 255
            self.init(red: r, green: g, blue: b, alpha: 1)
            return
        }
    }
    
    return nil
}

使用修正后代码解析#80478295,得到的分量为R≈0.278、G≈0.510、B≈0.584、A≈0.502,和预期值的微小差异为浮点计算精度误差,显示效果完全符合要求。

内容的提问来源于stack exchange,提问作者venky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 01:30:53