返回

iOS 14+ 中 UILabel 添加 CAGradientLayer 失败的原因探析

IOS

UILabel 的专有图层

UILabel 使用了一个专有图层 _UILabelContentLayer,负责文本绘制。如果在 UILabel 上添加一个 CAGradientLayer,它会成为 UILabel 的子图层之一。不过,_UILabelContentLayer 的 zPosition 属性是 0,而 CAGradientLayer 的 zPosition 属性默认是 1。因此,CAGradientLayer 会覆盖 _UILabelContentLayer,导致文本无法正常绘制。

解决方案

解决此问题的一种方法是隐藏 _UILabelContentLayer。您可以使用 clearColor 属性设置 _UILabelContentLayer 的 backgroundColor 为 UIColor.clear。这样,_UILabelContentLayer 就不会再绘制任何内容,CAGradientLayer 就会正常显示。

_UILabelContentLayer.backgroundColor = UIColor.clear

另一种方法是将 CAGradientLayer 的 zPosition 属性设置为负数。这样,CAGradientLayer 就位于 _UILabelContentLayer 的后面,文本就可以正常绘制了。

CAGradientLayer.zPosition = -1

需要注意的是,这两种方法都会降低 UILabel 的性能。这是因为,在绘制文本时,UILabel 需要先绘制 _UILabelContentLayer,再绘制 CAGradientLayer。如果 _UILabelContentLayer 被隐藏或 CAGradientLayer 的 zPosition 属性被设置为负数,UILabel 就需要先绘制 CAGradientLayer,再绘制 _UILabelContentLayer。这会增加 UILabel 的绘制时间。

总结

在 iOS 14 及更高版本中,UILabel 添加 CAGradientLayer 可能会失败。这是因为,UILabel 使用了专有图层 _UILabelContentLayer,负责文本绘制。如果在 UILabel 上添加一个 CAGradientLayer,它会成为 UILabel 的子图层之一。不过,_UILabelContentLayer 的 zPosition 属性是 0,而 CAGradientLayer 的 zPosition 属性默认是 1。因此,CAGradientLayer 会覆盖 _UILabelContentLayer,导致文本无法正常绘制。

您可以通过以下两种方法解决此问题:

  • 隐藏 _UILabelContentLayer
  • 将 CAGradientLayer 的 zPosition 属性设置为负数

请注意,这两种方法都会降低 UILabel 的性能。