删除子视图然后将其添加回来

Removing a subview then adding it back

我有一个带有渐变子视图的 UICollectionViewCell。 在我的视图控制器中,我有排序 CoreData 的按钮,然后是 UICollectionView 上的 reloadData()。 为了避免我的渐变子视图被一次又一次地绘制(就像过去发生的那样),我在 prepareForReuse() 中实现了 removeFromSuperview()。 在那里,我还实现了一个跟踪梯度存在的标志,因此我仍然在加载单元格时添加一个新的梯度。 但是在删除渐变后,我的 willMove(toSuperview: ) 不起作用,并且不会出现渐变视图。 我的逻辑有什么问题?

class CollectionCell: UICollectionViewCell {

@IBOutlet weak var mealImg: UIImageView!
@IBOutlet weak var mealTitleLbl: UILabel!
@IBOutlet weak var gradientView: UIView!

var gradientWasRemoved = false

func configureCell(meal: Meal) {
    mealTitleLbl.text = meal.title

    let img = meal.getMealImage()
    mealImg.image = img

    addGradient()    
}

  func addGradient () {
    let gradient = CAGradientLayer()
    gradient.frame = gradientView.bounds
    let topColor = UIColor(red:0.07, green:0.07, blue:0.07, alpha:1)
    let botomColor = UIColor.clear
    gradient.colors = [topColor.cgColor, botomColor.cgColor]
    gradientView.layer.insertSublayer(gradient, at: 0)

    if gradientWasRemoved == true {
        gradientView.willMove(toSuperview: self)
    } 
}

override func prepareForReuse() {
    super.prepareForReuse()

   gradientView.removeFromSuperview()
   gradientWasRemoved = true
}
}

我能够通过以下方式修复逻辑。 在 UICollectionViewCell class:

import UIKit

class CollectionCell: UICollectionViewCell {

@IBOutlet weak var mealImg: UIImageView!
@IBOutlet weak var gradientView: UIView!

@IBOutlet weak var mealTitleLbl: UILabel!

var gradientWasRemoved = false

func configureCell(meal: Meal) {
    mealTitleLbl.text = meal.title

    let img = meal.getMealImage()
    mealImg.image = img

    addGradient()
}

  func addGradient () {

    let gradient = CAGradientLayer()
    gradient.frame = gradientView.bounds
    let topColor = UIColor(red:0.07, green:0.07, blue:0.07, alpha:1)
    let botomColor = UIColor.clear
    gradient.colors = [topColor.cgColor, botomColor.cgColor]

    if gradientWasRemoved == false {
    gradientView.layer.insertSublayer(gradient, at: 0)
    } else if gradientWasRemoved == true {
        self.addSubview(gradientView)
    }
}

override func prepareForReuse() {
    super.prepareForReuse()

   gradientView.removeFromSuperview()
   gradientWasRemoved = true
}

}

prepareForReuse( ) 中我没有删除 gradientView,我从 Superview 中删除了它。我在那里设置了它被删除的标志。 由于我没有 nil 我的 gradientView 我能够 运行 addGradient() 并访问 gradientView.bounds 以创建新的 CGGradientLayer。 在向 gradientView 添加新层之前,我执行了 if 检查。如果我们确实删除了 gradientView,那么我们不会添加新的 CGGradientLayer,而只是将我们的 gradientView 放回去。 这样我们只将 CGGradientLayer 添加到我们的 gradientView 一次。

我了解到,通过从 Superview 中删除视图,它们仍然存在并且可以编辑。

感谢@Luis 和@LeoDabus 的贡献。