IBAnimatable 动画队列管理:链式调用与 completion 回调

IBAnimatable 动画队列管理:链式调用与 completion 回调

【免费下载链接】IBAnimatable IBAnimatable/IBAnimatable: IBAnimatable 是一个为 iOS 平台设计的开源库,允许开发者在 Interface Builder 中使用 storyboard 直接创建出丰富的交互动画和自定义界面元素,无需编写代码或少量代码即可实现原型到产品的转变。 【免费下载链接】IBAnimatable 项目地址: https://gitcode.com/gh_mirrors/ib/IBAnimatable

你是否还在为 iOS 动画的顺序执行和回调处理而烦恼?IBAnimatable 通过 AnimationPromiseAnimationChainable 协议提供了优雅的解决方案,让复杂动画队列像搭积木一样简单。本文将详解如何通过链式调用编排动画序列,并精准控制每个动画的完成回调。

核心原理:动画队列的数据结构

IBAnimatable 的动画队列基于 AnimationPromise 类实现,其核心数据结构定义在 Sources/Others/AnimationChainable.swift 中:

public class AnimationPromise<T: UIView> where T: Animatable {
  private var view: T
  private var animationList = [AnimationTuple]() // 存储动画元组队列
  private var completion: AnimatableCompletion? // 队列完成回调
}

每个动画元组包含动画类型和配置信息:

typealias AnimationTuple = (type: AnimationType, configuration: AnimationConfiguration)
struct AnimationConfiguration {
  let damping: CGFloat      // 弹性阻尼
  let velocity: CGFloat     // 初始速度
  let duration: TimeInterval // 持续时间
  let delay: TimeInterval   // 延迟时间
  let force: CGFloat        // 动画强度
  let timingFunction: TimingFunctionType // 时间曲线
}

链式调用:构建动画序列

通过 then() 方法可将动画按顺序添加到队列,支持链式语法:

// 示例:按钮点击后的动画序列
button.animate(.pop(repeatCount: 1))
     .then(.slide(.in, direction: .left), duration: 0.5)
     .delay(0.3) // 延迟0.3秒执行下一个动画
     .then(.fade(.out), damping: 0.7)
     .completion {
         print("所有动画执行完毕")
     }

关键方法解析

  1. animate() 启动队列
    Sources/Protocols/Animatable/Animatable.swift 中定义:

    @discardableResult
    func animate(_ animation: AnimationType) -> AnimationPromise<Self> {
      return AnimationPromise(view: self).delay(delay).then(animation)
    }
    
  2. then() 添加动画
    每次调用会创建新的动画元组并加入队列:

    public func then(_ animation: AnimationType, duration: TimeInterval? = nil) -> AnimationPromise {
      let config = AnimationConfiguration(
        damping: damping ?? view.damping,
        duration: duration ?? view.duration,
        // 其他配置参数...
      )
      animationList.append((animation, config))
      return self // 返回自身实现链式调用
    }
    

回调机制:监控动画生命周期

单个动画完成回调

每个动画执行完毕后通过 promise.animationCompleted() 触发队列推进:

func animationCompleted() {
  animationList.removeFirst() // 移除已完成动画
  if let nextAnimation = animationList.first {
    view.doAnimation(nextAnimation.type, configuration: nextAnimation.configuration, promise: self)
  } else {
    completion?() // 所有动画完成,触发最终回调
  }
}

队列完成回调

通过 completion() 方法设置整个队列的结束处理:

public func completion(_ completion: AnimatableCompletion?) {
  self.completion = completion
}

高级应用:并行动画与复合动画

并行执行多个动画

使用 .compound 动画类型可在一个步骤中并行执行多个动画:

button.animate(.compound([.scale(1,1,1.5,1.5), .rotate(.cw, repeatCount: 1)], run: .parallel))
     .then(.fade(.out), duration: 0.3)

复杂序列控制

结合延迟和并行动画创建更复杂的交互效果:

// 登录表单加载动画
usernameField.animate(.slide(.in, direction: .right), duration: 0.4)
passwordField.delay(0.1).animate(.slide(.in, direction: .right), duration: 0.4)
loginButton.delay(0.2).animate(.zoom(.in), duration: 0.5)

实战案例:购物车添加动效

以下是商品添加到购物车的完整动画序列实现:

func addToCartAnimation(for productView: UIView, cartButton: UIButton) {
  // 1. 商品缩放并淡出
  productView.animate(.compound([
    .scale(1,1,0.5,0.5), 
    .fade(.out)
  ], run: .parallel), duration: 0.3)
  .completion {
    // 2. 购物车按钮弹跳提示
    cartButton.animate(.pop(repeatCount: 2), duration: 0.6)
  }
}

性能优化建议

  1. 避免过度动画:同时执行不超过3个并行动画
  2. 重用配置:通过 AnimationConfiguration 共享常用参数
  3. 及时清理:复杂场景下调用 stopAnimations() 避免内存泄漏

总结与最佳实践

IBAnimatable 的动画队列管理通过链式调用和回调机制,大幅简化了复杂动画序列的实现。核心优势包括:

  • 代码可读性:链式语法直观反映动画执行顺序
  • 灵活性:支持串行/并行混合编排
  • 精确控制:完善的生命周期回调机制

建议在实际开发中:

  1. 将常用动画序列封装为扩展方法
  2. 复杂交互使用 AnimationPromise 手动管理队列
  3. 始终在 completion 中处理后续业务逻辑

完整实现细节可参考:

通过这些工具,你可以轻松实现丝滑流畅的iOS交互动画,提升用户体验的同时保持代码的可维护性。

【免费下载链接】IBAnimatable IBAnimatable/IBAnimatable: IBAnimatable 是一个为 iOS 平台设计的开源库,允许开发者在 Interface Builder 中使用 storyboard 直接创建出丰富的交互动画和自定义界面元素,无需编写代码或少量代码即可实现原型到产品的转变。 【免费下载链接】IBAnimatable 项目地址: https://gitcode.com/gh_mirrors/ib/IBAnimatable

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值