Swift5 给View扩展一个抖动的动画

给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()
    }
}

你可能感兴趣的:(Swift5 给View扩展一个抖动的动画)