如何停止使用渐变 UICollectionCell 创建新图层?覆盖 func prepareForReuse()

Posted

技术标签:

【中文标题】如何停止使用渐变 UICollectionCell 创建新图层?覆盖 func prepareForReuse()【英文标题】:How to stop creating a new layer with gradient UICollectionCell ? override func prepareForReuse() 【发布时间】:2019-05-11 10:52:59 【问题描述】:

我有一个UICollectionViewCell,带有渐变的图像和按钮。当我滚动时 - 我有一个错误:渐变在图像上绘制了一个新图层,并且按钮中的文本消失了。当我向后滚动时会发生这种情况。我想我应该使用覆盖func prepareForReuse()。但我不知道该怎么做。也许有人可以编写可以修复错误的代码,因为我不知道该怎么做。

import UIKit

class TrainingProgramCollectionViewCell: UICollectionViewCell 

private var gradient = CAGradientLayer()
@IBOutlet weak var bgView: UIView!

@IBOutlet weak var buttonOutlet: UIButton!

@IBOutlet weak var featuredImageView: UIImageView!

@IBOutlet weak var descriptionLabel: UILabel!
@IBOutlet weak var titleLabel: UILabel!

var trainingPrograms: TrainingProgram? 
    didSet 
        self.updateUI()
    


private func updateUI()

    if let trainingProgram = trainingPrograms 
        featuredImageView.image = trainingPrograms!.featuredImage
        titleLabel.text = trainingPrograms!.title
        descriptionLabel.text = trainingPrograms!.description
       // bgView.layer.cornerRadius = 10
      // buttonOutlet.backgroundColor = UIColor(red: 21/255, green: 126/255, blue: 238/255, alpha: 1)
        buttonOutlet.setGradientBackground(colorOne: UIColor(red: 0, green: 0.52, blue: 1, alpha: 1), colorTwo:  UIColor(red: 0, green: 0.39, blue: 0.81, alpha: 1), cornerRadius: 25)
        buttonOutlet.layer.cornerRadius = 25
        buttonOutlet.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.4).cgColor
        buttonOutlet.layer.shadowOffset = CGSize(width: 0, height: 5)
        buttonOutlet.layer.shadowRadius = 15
        buttonOutlet.layer.shadowOpacity = 1
        bgView!.layer.cornerRadius = 20

        featuredImageView.contentMode = .scaleAspectFill

        let view = UIView(frame: featuredImageView.frame)
        view.clipsToBounds = true

       // view.contentMode = .scaleAspectFill
        featuredImageView.clipsToBounds = true

        let gradient = CAGradientLayer()
        gradient.frame = view.frame

        gradient.colors = [UIColor(red: 0, green: 0.48, blue: 1, alpha: 0).cgColor,UIColor(red: 0, green: 0.48, blue: 1, alpha: 1).cgColor]
        gradient.locations = [0.1, 1.0]
        view.layer.insertSublayer(gradient, at: 0)
        featuredImageView.addSubview(view)
        featuredImageView.bringSubviewToFront(view)

     else 
        featuredImageView.image = nil
        titleLabel.text = nil
        descriptionLabel.text = nil
    


override func layoutSubviews() 
    super.layoutSubviews()

    self.layer.cornerRadius = 3.0
    layer.shadowRadius = 10
    layer.shadowOpacity = 0.2
    layer.shadowOffset = CGSize(width: 5, height: 10)

    self.clipsToBounds = false


override func prepareForReuse() 
    super.prepareForReuse()


为按钮设置渐变

extension UIView 

func setGradientBackground(colorOne: UIColor, colorTwo: UIColor, cornerRadius: CGFloat) 

let gradientLayer = CAGradientLayer()
gradientLayer.frame = self.bounds
gradientLayer.colors = [colorOne.cgColor, colorTwo.cgColor]
gradientLayer.locations = [0.0, 1.0]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
gradientLayer.cornerRadius = cornerRadius

layer.insertSublayer(gradientLayer, at: 0)

【问题讨论】:

setGradientBackground 中的gradientLayer 设为存储属性,并在prepareForReuse 中使用buttonOutlet.gradientLayer.removeFromSuperlayer() 【参考方案1】:

试试这个

    var gradLayer: CAGradientLayer! = layer.sublayers?.first(where:  $0.name == "grad_layer" ) as? CAGradientLayer
    if gradLayer == nil 
        gradLayer = CAGradientLayer()
        gradLayer.name = "grad_layer"
        layer.addSublayer(gradLayer)
    
    // do your changes to grad layer

    // edited
    gradient.frame = self.bounds

【讨论】:

我需要替换 let gradient = CAGradientLayer() gradient.frame = view.frame 吗?并使用您的代码?

以上是关于如何停止使用渐变 UICollectionCell 创建新图层?覆盖 func prepareForReuse()的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionCell 位置问题

通过单击 UICollectionCell 上的按钮执行 segue

带有 UICollectionViewDelegateFlowLayout 的 UIcollectioncell 在添加约束后不应用高度和宽度

停止 LinearGradientBrush 重复

iOS10 +渐变停止工作[重复]

更改自定义 UICollectionCell 中标签的边框宽度