给View扩展一个抖动的动画
方法一:
extension UIView {
/// 扩展UIView增加抖动方法
///
/// - Parameters:
/// - isVertical: 抖动方向(默认是水平方向)
/// - times: 抖动次数(默认5次)
/// - interval: 每次抖动时间(默认0.1秒)
/// - delta: 抖动偏移量(默认2)
/// - completion: 抖动动画结束后的回调
public func shake(_ isVertical: Bool = false,
_ times: Int = 5,
_ interval: TimeInterval = 0.1,
_ delta: CGFloat = 2,
_ completion: (() -> ())? = nil) {
// 播放动画
UIView.animate(withDuration: interval) {
var transform = CGAffineTransform(translationX: 0, y: delta)
if isVertical == true {
transform = CGAffineTransform(translationX: delta, y: 0)
}
self.layer.setAffineTransform(transform)
} completion: {_ in
// 如果当前是最后一次抖动,则将位置还原,并调用完成回调函数
if (times == 0) {
UIView.animate(withDuration: interval) {
self.layer.setAffineTransform(CGAffineTransform.identity)
} completion: { _ in
completion?()
}
}else {
// 如果当前不是最后一次抖动,则继续播放动画(总次数减1,偏移位置变成相反的)
self.shake(isVertical, times - 1, interval, -delta, completion)
}
}
}
}
方法二:
extension UIView {
/// SwifterSwift: 摇动视图的方向
///
/// - horizontal: 水平
/// - vertical: 垂直
public enum ShakeDirection {
case horizontal
case vertical
}
/// SwifterSwift: 摇动动画类型
///
/// - linear: 线性动画
/// - easeIn: 缓入动画
/// - easeOut: 缓出动画
/// - easeInOut: 缓入缓出动画
public enum ShakeAnimationType {
case linear
case easeIn
case easeOut
case easeInOut
}
/// SwifterSwift: 摇动视图.
///
/// - Parameters:
/// - direction: 摇动方向(水平或垂直),(默认为 .horizontal)
/// - duration: 以秒为单位的动画持续时间(默认为 1 秒)。
/// - animationType: 摇动动画类型(默认为 .easeOut)。
/// - completion: 在动画完成时运行的可选完成处理程序(默认值为 nil)。
public func shake(direction: ShakeDirection = .horizontal, duration: TimeInterval = 1, animationType: ShakeAnimationType = .easeOut, completion:(() -> Void)? = nil) {
CATransaction.begin()
let animation: CAKeyframeAnimation
switch direction {
case .horizontal:
animation = CAKeyframeAnimation(keyPath: "transform.translation.x")
case .vertical:
animation = CAKeyframeAnimation(keyPath: "transform.translation.y")
}
switch animationType {
case .linear:
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
case .easeIn:
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeIn)
case .easeOut:
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut)
case .easeInOut:
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
}
CATransaction.setCompletionBlock(completion)
animation.duration = duration
animation.values = [-20.0, 20.0, -20.0, 20.0, -10.0, 10.0, -5.0, 5.0, 0.0 ]
layer.add(animation, forKey: "shake")
CATransaction.commit()
}
}
网友评论