一、直接实现某个视图的持续抖动、只需要给视图的layer添加动画就行。
/// 直接实现
/// - Parameters:
/// - repeatCount: 重复次数
/// - duration: 持续时间
/// - values: //抖动幅度数组:不需要太大:从-15度 到 15度、再回到原位置、为一个抖动周期
/// - Returns: 返回动画 CAKeyframeAnimation
func shakeAnimate(repeatCount:Float,duration:CFTimeInterval,values:[Any]) -> CAKeyframeAnimation {
let keyAnimation:CAKeyframeAnimation = CAKeyframeAnimation(keyPath: "transform.rotation")
keyAnimation.delegate = self
//开始时间
keyAnimation.beginTime = CACurrentMediaTime()
//持续时间 0.2
keyAnimation.duration = duration
keyAnimation.values = values
//重复次数 3
keyAnimation.repeatCount = repeatCount
//完成后是否移除
keyAnimation.isRemovedOnCompletion = true
return keyAnimation
}
调用方式为
giftBtn.layer.add(self.shakeAnimate(repeatCount: MAXFLOAT, duration: 0.2, values: [-M_PI/12, M_PI/12,-M_PI/12]), forKey: nil)
代理中需要移除完成后的动画对象
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
if flag {
self.giftBtn.layer.removeAnimation(forKey: "transform.rotation")
}
}
二、实现间歇性的抖动动画、考虑了两种定时器
1、Timer
self.timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(animationBegin), userInfo: nil, repeats: true)
@objc func animationBegin(){
giftBtn.layer.add(self.shakeAnimate(repeatCount: 3.0, duration: 0.2, values: [-M_PI/12, M_PI/12,-M_PI/12]), forKey: nil)
}
2、DispatchSourceTimer
/// 抖动动画
/// - Parameters:
/// - layer: 传入需要动画的视图的layer
/// - values: 抖动周期点位 [-M_PI/12, M_PI/12,-M_PI/12]
/// - duration: 一周期持续时间
///
func shakeAnimation(layer:CALayer,values:[Any],duration:CFTimeInterval){
dispatchTimer = DispatchSource.makeTimerSource(flags:[], queue: DispatchQueue.global())
/*
deadline 计时器最迟开始时间;
repeating 时间间隔;
leeway 指的是一个期望的容忍时间,将它设置为1毫秒,意味着系统有可能在定时器时间到达的前1毫秒或者后1毫秒才真正触发定时器。
*/
dispatchTimer?.schedule(deadline: DispatchTime.now()+1, repeating: DispatchTimeInterval.seconds(2), leeway: .milliseconds(1))
//执行timer
dispatchTimer?.setEventHandler (handler: {[weak self] in
DispatchQueue.main.sync {
//抖动动画
layer.add(self?.shakeAnimate(repeatCount: 3.0, duration: duration, values: values) ?? CAKeyframeAnimation(), forKey: nil)
}
})
//开始执行
dispatchTimer?.resume()
}
Demo地址:https://github.com/HolothurianC/ShakeAnimation