问题
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