以拨打视频电话时的拨打按钮抖动为例
import UIKit
class PACallPrepareAlertView: UIView {
@IBOutlet weak var callIV: UIImageView!
private var isLeave: Bool = false
deinit {
isLeave = true
}
override func awakeFromNib() {
super.awakeFromNib()
shakeAction()
}
private func shakeAction() {
if isLeave { return } // 避免无限套娃
callIV.shake(false, 2, 0.2, 1) { [weak self] in
self?.shakeAction()
}
}
@IBAction func tapReturnAction(_ sender: Any) {
isLeave = true
}
}
import Foundation
extension UIView {
/// 扩展UIView增加抖动方法。使用时,要避免离开页面后方法仍然在调用。
/// - Parameters:
/// - isVertical: 抖动方向(默认是水平方向)
/// - times: 抖动次数(默认5次)
/// - interval: 每次抖动时间(默认0.1秒)
/// - delta: 抖动偏移量
/// - 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?
if isVertical == true {
transform = CGAffineTransform(translationX: delta, y: 0)
} else {
transform = CGAffineTransform(translationX: 0, y: delta)
}
self.layer.setAffineTransform(transform!)
} completion: {_ in
if (times == 0) {
UIView.animate(withDuration: interval) {
self.layer.setAffineTransform(CGAffineTransform.identity)
} completion: { _ in
completion?()
}
} else {
self.shake(isVertical, times - 1, interval, -delta, completion)
}
}
}
}
示意图: