【问题标题】:Apply gradient to label in UICollectionViewCell将渐变应用于 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 行代码?这可能会解决问题。

标签: swift uicollectionview uicollectionviewcell uicollectionviewlayout snapkit


【解决方案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)

        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 2017-08-11
    • 2013-08-22
    • 2021-11-20
    相关资源
    最近更新 更多