如何在循环中让UIView执行n次动画并追踪每个动画事件
实现可追踪的n次UIView重复动画
我来帮你解决这个问题!想要实现重复n次的UIView动画同时追踪每一次动画事件,UIView.setAnimationRepeatCount确实没法单独追踪每个循环的完成状态——它只是简单重复整个动画块,没法在单次循环结束后插入自定义逻辑。咱们可以用递归调用动画块的方式来实现,既能控制重复次数,又能精准追踪每一次动画的完成事件。
方案:递归式可追踪重复动画
这个方案的核心思路是:每次完成一轮动画(你的场景里是「滑出+滑回」)后,计数器加一,判断是否达到目标重复次数,若未达到则递归启动下一轮动画,同时在每个动画的完成回调里加入追踪逻辑。
完整代码示例
import UIKit class YourViewController: UIViewController { @IBOutlet weak var vwObj: UIView! @IBOutlet weak var leading: NSLayoutConstraint! // 配置重复次数 private let targetRepeatTimes = 3 // 替换成你需要的n值 private var currentCompletedTimes = 0 override func viewDidLoad() { super.viewDidLoad() // 启动动画 startRepeatableAnimation() } private func startRepeatableAnimation() { guard currentCompletedTimes < targetRepeatTimes else { // 所有重复动画完成后的收尾操作 print("✅ 全部\(targetRepeatTimes)次动画执行完毕") return } // 第一步:滑出动画 UIView.animate(withDuration: 3.0, animations: { self.leading.constant = self.view.frame.size.width + self.vwObj.frame.size.width self.view.layoutIfNeeded() }, completion: { [weak self] isFinished in guard let self = self, isFinished else { return } // 追踪滑出动画完成事件 print("🔹 第\(self.currentCompletedTimes + 1)次滑出动画完成") // 第二步:滑回动画 UIView.animate(withDuration: 3.0, animations: { self.leading.constant = -(self.vwObj.frame.size.width) self.view.layoutIfNeeded() }, completion: { [weak self] isFinished in guard let self = self, isFinished else { return } // 追踪滑回动画完成事件 print("🔹 第\(self.currentCompletedTimes + 1)次滑回动画完成") // 更新计数器,启动下一轮动画 self.currentCompletedTimes += 1 self.startRepeatableAnimation() }) }) } }
关键细节说明
- 内存安全:在动画的
completion闭包里使用[weak self]避免循环引用,防止控制器无法被释放。 - 精准追踪:你可以在两个
completion闭包里替换打印日志的代码,比如更新UI状态、发送统计事件等自定义逻辑。 - 灵活控制:如果需要中途停止动画,只需在合适的时机修改
currentCompletedTimes为targetRepeatTimes即可。
为什么不用UIView.setAnimationRepeatCount?
UIView.setAnimationRepeatCount是基于旧版UIView动画API的,它的局限性在于:
- 只能重复整个动画块,无法拆分追踪单次循环的完成状态;
- 属于类方法级别的全局设置,在复杂动画场景下容易出现冲突;
- 不支持在重复过程中动态调整动画逻辑。
相比之下,递归式的block动画方案更灵活,完全满足你「重复n次+追踪每个动画事件」的需求。
内容的提问来源于stack exchange,提问作者subhajit poddar
相关产品推荐
相关产品推荐

