将渐变应用于 UICollectionViewCell 中的标签

Posted

技术标签:

【中文标题】将渐变应用于 UICollectionViewCell 中的标签【英文标题】:Apply gradient to label in UICollectionViewCell 【发布时间】:2020-06-16 21:04:32 【问题描述】:

我正在尝试将渐变应用到 UICollectionView 中一个单元格中的 UILabel。

根据网上的一些回复,我将扩展添加到 UIImage:

extension UIImage 
    static func gradientImageWithBounds(bounds: CGRect, colors: [CGColor]) -> UIImage 
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = bounds
        gradientLayer.colors = colors
        gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
        gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)

        UIGraphicsBeginImageContext(gradientLayer.bounds.size)
        if let context = UIGraphicsGetCurrentContext() 
            gradientLayer.render(in: context )
            let image = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            return image!

        
        return UIImage()
    

当我将它应用于普通标签时,它就像一个魅力:

let gradientImage = UIImage.gradientImageWithBounds(bounds: someLabel.bounds, colors: [UIColor.black.cgColor, UIColor.white.cgColor])
someLabel.textColor = UIColor.init(patternImage: gradientImage)

问题是,我想应用渐变的标签是 UICollectionViewCell 的一部分,当我尝试这样做时:

override init(frame: CGRect) 
        super.init(frame: frame)

        addSubview(nameLabel)
        nameLabel.snp.makeConstraints  (make) in
            make.top.bottom.trailing.equalToSuperview()
            make.leading.equalToSuperview().inset(10)
        

        let gradientImage = UIImage.gradientImageWithBounds(bounds: nameLabel.bounds, colors: [UIColor.black.cgColor, UIColor.white.cgColor])
        nameLabel.textColor = UIColor.init(patternImage: gradientImage)
    

它不起作用。 当我在创建 gradientImage 之前停止执行时,不幸的是 nameLabel.bounds 等于 0:

(lldb) po nameLabel.bounds
▿ (0.0, 0.0, 0.0, 0.0)
  ▿ origin : (0.0, 0.0)
    - x : 0.0
    - y : 0.0
  ▿ size : (0.0, 0.0)
    - width : 0.0
    - height : 0.0

有没有办法在 UICollectionViewCell 定义中获取标签的边界?这是否取决于我如何定义 UICollectionView?我错过了什么?

或者,您知道在 UICollectionViewCell 内使用渐变标签的其他方法吗?

我尝试将尺寸设置为:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
return CGSize(width: 100, height: 60)

我尝试将布局的定义从自动更改为

layout.estimatedItemSize = CGSize(width: 100, height: 60)

似乎没有任何帮助。

【问题讨论】:

这可能是因为在初始化期间,尚未定义框架。您可以做的是在 cellForItem 函数内为标签设置文本时应用它。 @rs7 我实际上是从那里开始的,但是在 cellForItemAt 函数中,nameLabel.bounds 仍然为 0。但是,我再次尝试了,发现 cell.bounds 不是 0,我可以工作有了这个,谢谢!我想知道为什么标签本身的框架还没有定义…… 不客气。再次查看您的代码后,我注意到您将视图布置在闭包内。您是否尝试过在闭包内移动相关的 2 行代码?这可能会解决问题。 【参考方案1】:

我认为问题可能在于您在闭包中异步布置视图。换句话说,在你的视图布局之前,下面的语句会被执行,这可以解释为什么还没有设置边界。

override init(frame: CGRect) 
        super.init(frame: frame)

        addSubview(nameLabel)
        nameLabel.snp.makeConstraints  (make) in
            make.top.bottom.trailing.equalToSuperview()
            make.leading.equalToSuperview().inset(10)
            let gradientImage = UIImage.gradientImageWithBounds(bounds: nameLabel.bounds, colors: [UIColor.black.cgColor, UIColor.white.cgColor])
            self.nameLabel.textColor = UIColor.init(patternImage: gradientImage)

        
    

【讨论】:

以上是关于将渐变应用于 UICollectionViewCell 中的标签的主要内容,如果未能解决你的问题,请参考以下文章

将渐变应用于 UICollectionViewCell 中的标签

如何将渐变边框颜色应用于 UIButton?

如何将渐变应用于多个自定义 uiview?

将渐变应用于按钮不会迅速反映

以编程方式将渐变边框颜色应用于 UIButton

将线性透明渐变应用于python中具有透明背景的图像部分