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
相关产品推荐
相关产品推荐

