setNeedsLayout
手动标记该视图的布局发生变化,在下一个周期调用 layoutSubviews 更新
layoutIfNeeded
检查视图的布局是否被标记发生变化,如有变化立即调用 layoutSubviews
第一步创建CADisplayLink,可以监听到每一帧的回调
var animTimer = CADisplayLink.init(target: self, selector: #selector(animStep))
// animTimer?.frameInterval = 60 //定义多少帧回调一次
guard animTimer == nil else {
animTimer!.add(to: .main, forMode: .default)
return
}
在回调中调用setNeedsLayout触发刷新,会在下一帧回调layoutSubviews,在这个方法中重新设置子view的属性,实现动画的效果。
第一次写代码的时候,习惯性在layoutSubviews布局子view,所以任务做动画要重新出发layoutSubviews。直接在animStep中设置改变子view的属性也是可以触发重新绘制的。
private var animProgress = 0
private var duration = 2.0
private var animPercent = 0.0
//一秒刷新60次
@objc
func animStep(){
animProgress+=1
setNeedsLayout()
// print("animProgress==",animProgress)
animPercent = CGFloat(animProgress) / (duration * 60 * 1.0)
if(animPercent >= 1){
animTimer?.remove(from: .main, forMode: .default)
self.animFinishListener?.onFinish()
}
}