问题
I have a UICollectionViewCell with a gradient subview.
In my view controller, I have buttons that are sorting CoreData and then reloadData() on the UICollectionView.
To avoid my gradient subview to be drawn again and again (as it happened in the past), I implement removeFromSuperview() in prepareForReuse().
There I also implement a flag that keeps track of gradient existence so I still add a new gradient when cell is load.
However after removing the gradient, my willMove(toSuperview: ) doesn't work, and gradient view doesn't appear.
What's wrong with my logic?
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
}
}
回答1:
I was able to fix the logic with following. In 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
}
}
In prepareForReuse( ) I didn't delete gradientView, I removed it from the Superview. I set the flag there that it was removed.
Since I didn't nil my gradientView i was able to run addGradient() and access gradientView.bounds for creation of new CGGradientLayer.
Right before adding a new layer to gradientView, I performed if check. If we did remove gradientView then we don't add a new CGGradientLayer but simply put our gradientView back.
This way we add CGGradientLayer to our gradientView only once.
I learned that by removing views from Superview they are still alive and can be edited.
Thank you @Luis and @LeoDabus for your contribution.
来源:https://stackoverflow.com/questions/41948576/removing-a-subview-then-adding-it-back