Removing a subview then adding it back

主宰稳场 提交于 2019-12-25 09:27:17

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!