尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

如何用 Dance 实现可拖拽进度动画?交互式 scrubbing 动画完整实战

如何用 Dance 实现可拖拽进度动画?交互式 scrubbing 动画完整实战 如何用 Dance 实现可拖拽进度动画交互式 scrubbing 动画完整实战【免费下载链接】DanceA radical elegant animation library for iOS.项目地址: https://gitcode.com/gh_mirrors/dance1/Dance在 iOS 开发中可拖拽进度动画是视频播放器、音乐 App、视频剪辑工具里最常见的交互形式——用户拖动进度条画面实时跟随。Dance正是为此而生的 iOS 动画库它基于 iOS 10 的UIViewPropertyAnimator一行view.dance.animate { ... }即可创建动画并能随时暂停、反向、scrubbing拖动进度预览。本文将以完整实战的方式教你从零实现一个交互式 scrubbing 动画。Dance 动画库是什么为什么天生适合做拖拽进度动画Dance 是一款radical elegant的 iOS 动画库把UIViewPropertyAnimator的强大能力封装成了极其优雅的链式 API。它的核心理念是动画一旦创建就附着在视图上你可以在任何能引用到该视图的地方随时控制这段动画。circle.dance.animate(duration: 2.0, curve: .easeInOut) { $0.center endPosition $0.backgroundColor .systemBlue }.start()正是这种动画可被外部引用控制的设计让 Dance 做 scrubbing 动画得心应手——进度条拖到哪动画就渲染到哪全程无缝衔接。核心实现只有单个文件非常适合阅读Dance.swift。什么是 scrubbing 动画拖拽进度动画的核心原理 Scrubbing 一词源自视频剪辑像拖动播放器进度条一样把动画进度拖到任意位置。在UIViewPropertyAnimator中这对应fractionComplete属性0 表示动画起点1 表示终点。Dance 把它封装成了直观的progress属性源码见 Dance.swift概念说明progress 0动画处于起始状态progress 0.5动画正好进行到一半progress 1动画到达终点 理解这一点后实现可拖拽进度动画就只剩把手指/滑块的位置换算成 0~1 的数字这一步了。环境准备最快安装 Dance 动画库的方法 ⚡Dance 要求iOS 10、Swift 3安装方式二选一方式一CocoaPods推荐platform :ios, 10.0 target YourProject do use_frameworks! pod Dance end方式二直接拖入源码—— 将 Dance.swift 拖入 Xcode 工程同样可用。如果想把示例工程跑起来对照学习也可以直接 clone 仓库https://gitcode.com/gh_mirrors/dance1/Dance打开DanceExample.xcodeproj即可体验官方演示一个圆形视图沿直线运动用滑块实时拖拽进度。第一步创建一段可被拖拽的动画 先创建一段待命的动画。注意.animate {}只是定义动画不会立刻播放import Dance // 用 UIKit 内置曲线easeInOut / easeIn / easeOut / linear circle.dance.animate(duration: 2.0, curve: .linear) { $0.center endPosition }.addCompletion { position in print(动画结束位置\(position)) } // 需要时再启动 circle.dance.start()Dance 还支持四种时序方式UIKit 内置曲线、UISpringTimingParameters弹簧参数、自定义三次贝塞尔曲线、dampingRatio阻尼比你可以在 README.md 的 Usage 章节找到全部写法。第二步核心代码——用 progress 实现交互式 scrubbing 创建好动画后拖拽进度的核心代码只有一行// 方式一直接给 progress 赋值 circle.dance.progress 0.5 // 方式二链式调用 setProgress支持 Int / Float / Double / CGFloat circle.dance.setProgress(to: 0.5)你可能好奇如果动画还没启动直接设置进度会怎样Dance 做了很贴心的处理——在 Dance.swift 中setFractionComplete会自动启动并立即暂停动画然后才设置进度确保动画始终能被拖拽。这就是 Dance 的 forgiving宽容哲学替你兜住错误绝不崩溃。第三步用 UISlider 驱动拖拽进度动画完整实战️现在把滑块接到动画上。在 Storyboard 中放一个取值范围0.0 ~ 1.0的UISlider然后IBAction func sliderValueChanged(_ sender: UISlider) { // slider.value 恰好是 0~1直接映射为动画进度 circle.dance.setProgress(to: sender.value) }拖动滑块时动画会实时、无缝地跟随到对应位置——一个可拖拽进度动画就完成了官方示例工程就是这么实现的见 ViewController.swift它用了一个 10 秒的线性动画滑块拖到哪儿圆球就停在哪儿效果非常直观。第四步暂停、反向与完成——动画生命周期全控制 ️拖拽之外Dance 还提供了完整的动画控制组合拳circle.dance.pause() // 暂停动画 circle.dance.reverse() // 像倒放视频一样反向播放 circle.dance.isReversed true // 等价写法 circle.dance.finish(at: .current) // 结束动画渲染在当前位置并触发完成回调配合addCompletion你可以在动画结束.end、回到起点.start或停在当前进度.current时执行后续逻辑。例如拖拽松手后让动画从当前进度继续播放到终点就是播放器类 App 最常见的交互。进阶结合 UIPanGestureRecognizer 实现手指拖拽 scrubbing ✋滑块之外更原生的做法是用手势直接拖拽。核心思路是把手指位移换算成 0~1 的进度objc func handlePan(_ gesture: UIPanGestureRecognizer) { let translation gesture.translation(in: view) // 把 300pt 的位移映射为 0~1 的动画进度并做边界裁剪 let progress min(max(translation.x / 300, 0), 1) circle.dance.setProgress(to: progress) if gesture.state .ended { // 松手后进度超过一半则播完否则倒放回起点 circle.dance.progress 0.5 ? circle.dance.start() : circle.dance.reverse() } }这种拖拽 松手回弹的交互正是视频剪辑、卡片滑动等场景的标配体验。常见问题与调试技巧 控制不生效先检查circle.dance.hasAnimation是否为true——动画结束后关联的 animator 会被移除需要重新创建。看不到报错崩溃这是 Dance 的宽容设计。例如对没有动画的视图调用.start()它只会打印** Dance Error: view with dance.tag tag does not have an active animation! **而不会闪退。想追踪动画状态用circle.dance.state.active/.inactive、circle.dance.isRunning即可实时监控。总结 ✨借助 Dance 动画库实现可拖拽进度动画只需三步创建动画 → 把交互位置换算成 0~1 → 调用setProgress。相比手写CAAnimation或直接操作UIViewPropertyAnimatorDance 的链式 API 让代码更简洁、更易维护也让交互式 scrubbing 动画变得人人都能轻松上手。现在就打开示例工程 ViewController.swift 亲手试一试吧【免费下载链接】DanceA radical elegant animation library for iOS.项目地址: https://gitcode.com/gh_mirrors/dance1/Dance创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表