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

Swift开发:编程创建UILabel设置自定义十六进制文字颜色不生效求助

问题排查与解决方案

可能的原因及对应修复方案

1. 十六进制颜色格式与扩展不匹配

你当前使用的UIColor扩展仅支持带#前缀的8位十六进制字符串(格式为#RRGGBBAA,包含RGB三色通道+透明度通道),如果self.colorSelected存储的是常用的6位十六进制颜色(格式为#RRGGBB,无透明度),扩展会直接返回nil,强制解包color!会触发异常,也会导致颜色设置失败。
建议优化扩展兼容常见的6位、8位十六进制格式,参考代码如下:

extension UIColor {
    public convenience init?(hex: String) {
        let r, g, b, a: CGFloat
        var hexProcessed = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased()
        
        if hexProcessed.hasPrefix("#") {
            hexProcessed.removeFirst()
        }
        
        // 兼容6位(无透明度)和8位(带透明度)格式
        guard hexProcessed.count == 6 || hexProcessed.count == 8 else {
            return nil
        }
        
        var hexNumber: UInt64 = 0
        guard Scanner(string: hexProcessed).scanHexInt64(&hexNumber) else {
            return nil
        }
        
        if hexProcessed.count == 8 {
            r = CGFloat((hexNumber & 0xff000000) >> 24) / 255
            g = CGFloat((hexNumber & 0x00ff0000) >> 16) / 255
            b = CGFloat((hexNumber & 0x0000ff00) >> 8) / 255
            a = CGFloat(hexNumber & 0x000000ff) / 255
        } else { // 6位格式默认透明度为1
            r = CGFloat((hexNumber & 0xff0000) >> 16) / 255
            g = CGFloat((hexNumber & 0x00ff00) >> 8) / 255
            b = CGFloat(hexNumber & 0x0000ff) / 255
            a = 1.0
        }
        
        self.init(red: r, green: g, blue: b, alpha: a)
    }
}

2. 初始化时机错误

你将颜色设置逻辑写在了label的初始化闭包中,该闭包会在当前类实例初始化阶段执行,此时self.colorSelected大概率还没有完成赋值,取到的是空值或者默认值,导致颜色初始化失败。而你给其他视图设置背景色的逻辑通常是在viewDidLoad等属性赋值完成后的生命周期节点执行,所以可以正常生效。
修复方案:将颜色设置逻辑移到viewDidLoad中执行,参考代码如下:

// 先只初始化label的基础属性
let labelTextView: UILabel = {
    let labelView = CustomLabelForTextView()
    labelView.translatesAutoresizingMaskIntoConstraints = false
    labelView.font = UIFont(name: "Avenir-Medium", size: 20.0)
    labelView.text = "Hello World"
    labelView.backgroundColor = .clear
    // 先给默认颜色
    labelView.textColor = .darkGray
    return labelView
}()

override func viewDidLoad() {
    super.viewDidLoad()
    // 布局label逻辑不变
    View1.addSubview(labelTextView)
    NSLayoutConstraint.activate([
        labelTextView.centerXAnchor.constraint(equalTo: View1.centerXAnchor),
        labelTextView.centerYAnchor.constraint(equalTo: View1.centerYAnchor),
        labelTextView.widthAnchor.constraint(equalToConstant: 150), // 原宽度50过窄,文字会被截断,建议调整
        labelTextView.heightAnchor.constraint(equalToConstant: 30)
    ])
    
    // 此时self.colorSelected已经完成赋值,再设置颜色
    if UserDefaults.standard.bool(forKey: "colorSelectedForText") == true {
        let selectedColor = self.colorSelected
        if let color = UIColor(hex: selectedColor) {
            labelTextView.textColor = color
        }
    }
}

3. 自定义Label内部逻辑覆盖

检查你使用的CustomLabelForTextView类,是否存在以下逻辑:

  • 重写了textColor的setter方法,覆盖了外部传入的颜色
  • 在layoutSubviews、draw(_ rect: CGRect)等生命周期方法中重新给textColor赋值
  • 内部使用了attributedText富文本,富文本的属性会覆盖textColor的设置

4. 其他检查点

  • 加断点确认UserDefaults.standard.bool(forKey: "colorSelectedForText")是否返回true,是否进入了自定义颜色设置的分支
  • 原label宽度设置为50,20号字号的"Hello World"文字会被截断,建议调整宽度避免文字显示不全导致的颜色看起来未生效的问题
  • 检查后续业务逻辑中是否有其他代码重新修改了labelTextView的textColor属性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 15:18:01