在 reloadData() 之后重绘 UICollectionViewCell 失败
Fail to redraw UICollectionViewCell after reloadData()
我有一个 UICollectionViewCell:
"Gradient View" 是一个具有渐变的 UIView:
数据来源是CoreData。
在集合视图中,我有对 CoreData 进行排序的按钮:
@IBAction func allMealsBtn(_ sender: Any) {
let fetchRequest: NSFetchRequest<Meal> = Meal.fetchRequest()
let dateSort = NSSortDescriptor(key: "created", ascending: false)
fetchRequest.sortDescriptors = [dateSort]
let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
controller.delegate = self
self.controller = controller
do {
try controller.performFetch()
} catch {
let error = error as NSError
print("Couldn't fetch data from CoreData with error: \(error.debugDescription)")
}
collectionView.reloadData()
}
按下排序按钮后,集合视图会重新加载并显示正确的数据。
但是,渐变视图成倍增加,就好像单元格没有被破坏一样。
这是我多次排序数据后看到的:
如何确保我的单元格是从头开始重新绘制的?
编辑:
我的自定义单元格class。
所以在configureCell中我要检查我的gradientView是否添加到视图中,如果是,则添加渐变,如果没有,添加,并添加渐变。
我该如何做这项检查?
class 集合单元格:UICollectionViewCell {
@IBOutlet weak var mealImg: UIImageView!
@IBOutlet weak var mealTitleLbl: UILabel!
@IBOutlet weak var gradientView: UIView!
func configureCell(meal: Meal) {
mealTitleLbl.text = meal.title
let img = meal.getMealImage()
mealImg.image = img
gradientView.addGradientWithColor(color: UIColor.clear)
// How can I check if my gradientView is added to the view, if yes, then add gradient, if not, add it, and only then add gradient.
}
override func prepareForReuse() {
super.prepareForReuse()
gradientView.removeFromSuperview()
}
}
extension UIView {
func addGradientWithColor(color: UIColor) {
let gradient = CAGradientLayer()
gradient.frame = self.bounds
let topColor = UIColor(red:0.07, green:0.07, blue:0.07, alpha:1)
gradient.colors = [topColor.cgColor, color.cgColor]
self.layer.insertSublayer(gradient, at: 0)
}
}
编辑:
我放弃了扩展并实现了标志逻辑。
但是,删除视图后,它在执行搜索后永远不会重新出现在单元格中。
有什么想法吗?
class CollectionCell: UICollectionViewCell {
@IBOutlet weak var mealImg: UIImageView!
@IBOutlet weak var mealTitleLbl: UILabel!
@IBOutlet weak var gradientView: UIView!
var isGradientAdded = false
func configureCell(meal: Meal) {
mealTitleLbl.text = meal.title
let img = meal.getMealImage()
mealImg.image = img
if isGradientAdded == false {
addGradient()
isGradientAdded = true
}
}
override func prepareForReuse() {
super.prepareForReuse()
gradientView.removeFromSuperview()
}
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)
}
}
在 UICollectionViewCell
subclass (Cell) 中,您应该覆盖 prepeareForReuse
函数 - 将单元格转换为默认模式。
如果您没有 Cell
的自定义 class - 之前创建它并在界面生成器中将其分配为 class 用于您的 Cell
单元格(以及当然不要忘记奥特莱斯)
override func prepareForReuse() {
super.prepareForReuse()
//set cell to initial state here
//e.g try to remove you gradient view
yourGradientView.removeFromSuperview()
}
我有一个 UICollectionViewCell:
"Gradient View" 是一个具有渐变的 UIView:
数据来源是CoreData。 在集合视图中,我有对 CoreData 进行排序的按钮:
@IBAction func allMealsBtn(_ sender: Any) {
let fetchRequest: NSFetchRequest<Meal> = Meal.fetchRequest()
let dateSort = NSSortDescriptor(key: "created", ascending: false)
fetchRequest.sortDescriptors = [dateSort]
let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
controller.delegate = self
self.controller = controller
do {
try controller.performFetch()
} catch {
let error = error as NSError
print("Couldn't fetch data from CoreData with error: \(error.debugDescription)")
}
collectionView.reloadData()
}
按下排序按钮后,集合视图会重新加载并显示正确的数据。 但是,渐变视图成倍增加,就好像单元格没有被破坏一样。 这是我多次排序数据后看到的:
如何确保我的单元格是从头开始重新绘制的?
编辑:
我的自定义单元格class。 所以在configureCell中我要检查我的gradientView是否添加到视图中,如果是,则添加渐变,如果没有,添加,并添加渐变。 我该如何做这项检查?
class 集合单元格:UICollectionViewCell {
@IBOutlet weak var mealImg: UIImageView!
@IBOutlet weak var mealTitleLbl: UILabel!
@IBOutlet weak var gradientView: UIView!
func configureCell(meal: Meal) {
mealTitleLbl.text = meal.title
let img = meal.getMealImage()
mealImg.image = img
gradientView.addGradientWithColor(color: UIColor.clear)
// How can I check if my gradientView is added to the view, if yes, then add gradient, if not, add it, and only then add gradient.
}
override func prepareForReuse() {
super.prepareForReuse()
gradientView.removeFromSuperview()
}
}
extension UIView {
func addGradientWithColor(color: UIColor) {
let gradient = CAGradientLayer()
gradient.frame = self.bounds
let topColor = UIColor(red:0.07, green:0.07, blue:0.07, alpha:1)
gradient.colors = [topColor.cgColor, color.cgColor]
self.layer.insertSublayer(gradient, at: 0)
}
}
编辑: 我放弃了扩展并实现了标志逻辑。 但是,删除视图后,它在执行搜索后永远不会重新出现在单元格中。 有什么想法吗?
class CollectionCell: UICollectionViewCell {
@IBOutlet weak var mealImg: UIImageView!
@IBOutlet weak var mealTitleLbl: UILabel!
@IBOutlet weak var gradientView: UIView!
var isGradientAdded = false
func configureCell(meal: Meal) {
mealTitleLbl.text = meal.title
let img = meal.getMealImage()
mealImg.image = img
if isGradientAdded == false {
addGradient()
isGradientAdded = true
}
}
override func prepareForReuse() {
super.prepareForReuse()
gradientView.removeFromSuperview()
}
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)
}
}
在 UICollectionViewCell
subclass (Cell) 中,您应该覆盖 prepeareForReuse
函数 - 将单元格转换为默认模式。
如果您没有 Cell
的自定义 class - 之前创建它并在界面生成器中将其分配为 class 用于您的 Cell
单元格(以及当然不要忘记奥特莱斯)
override func prepareForReuse() {
super.prepareForReuse()
//set cell to initial state here
//e.g try to remove you gradient view
yourGradientView.removeFromSuperview()
}