问题场景:开发中遇到一个需求,是view的高度根据加在上边的label文字高度改变而发生改变,然后其背景色一个从左上角到右下角的渐变色。最初的实现方式是:
1.全局定义了一个渐变色属性的layer
var newGlayer: CAGradientLayer = CAGradientLayer()//渐变色layer
2.在viewDidLoad时,设置其属性,给layer一个起始高度,并建立其与topView的关系
let leftColor = UIColor.extColorWithHex("#FEB086", alpha: 1)
let rightColor = UIColor.extColorWithHex("#FF7767", alpha: 1)
let frameT = CGRect.init(x: 0, y: 0, width: SDJG_ScreenWidth, height: isiPhoneX ? 214 : 190)
let gradColor : [CGColor] = [leftColor.cgColor,rightColor.cgColor]
newGlayer.colors = gradColor
newGlayer.startPoint = CGPoint(x: 0, y: 0)
newGlayer.endPoint = CGPoint(x: 1, y: 0)
newGlayer.frame = frameT
topView.layer.insertSublayer(newGlayer, at: 0)
3.在拿到更新后的高度时,去重新设置layer的高度,并改边TopView的高度约束
let frameNew = CGRect.init(x: 0, y: 0, width: SDJG_ScreenWidth, height: entity.topTotalHeight)
newGlayer.frame = frameNew
self.topView.snp.updateConstraints { (maker) in
maker.height.equalTo(entity.topTotalHeight)
}
存在问题:在更新时,渐变色会有一个绘制过程,在大概0.5s的时间内,肉眼可见渐变色高度发生变化,有个过度闪动。
解决方案:用replace去代替add。将渐变色的属性不在设置为add在contentView的子视图topView上,而是将渐变色的属性直接设在contentView本身的layer属性上。
1.先定义一个渐变色属性layer
var selfLayer: CAGradientLayer = CAGradientLayer()//渐变色layer
2.重写layerClass方法,直接返回一个渐变色属性的layer给contentView
override class var layerClass: AnyClass {
get {
return CAGradientLayer.classForCoder()
}
}
3.把self.layer直接赋值给selfLazyer(注:这里是直接引用,而不是copy另一份,两着地址指向地址是同一个)
selfLayer = self.layer as! CAGradientLayer
4.只需要在viewDidLoad时设置其属性便可,这样渐变色的属性就会跟着contentView本身高度改变而直接改变了。
let leftColor = UIColor.extColorWithHex("#FEB086", alpha: 1)
let rightColor = UIColor.extColorWithHex("#FF7767", alpha: 1)
let gradColor : [CGColor] = [leftColor.cgColor,rightColor.cgColor]
selfLayer.colors = gradColor
selfLayer.startPoint = CGPoint(x: 0, y: 0)
selfLayer.endPoint = CGPoint(x: 1, y: 1)