如何给ScrollingStackViewController定制弹性动画:覆盖animate与scrollAnimate闭包的完整指南
【免费下载链接】ScrollingStackViewControllerA view controller that uses root views of child view controllers as views in a UIStackView.项目地址: https://gitcode.com/gh_mirrors/sc/ScrollingStackViewController
ScrollingStackViewController 是 iOS 上一个轻量的滚动容器控件:它把子视图控制器的根视图放进UIStackView,再用UIScrollView实现滚动,非常适合“少量、动态、富内容分区”的页面。刚集成时,默认的过渡动画偏“硬”,很多同学想把它调成更有弹性的效果——核心就在于本文的主角:覆盖animate与scrollAnimate两个公开闭包,几行代码就能换掉整套动画。
一图看懂:两个动画闭包各管什么
ScrollingStackViewController 把“分区显示/隐藏动画”和“滚动动画”拆成了两个独立可覆盖的闭包,这是定制弹性动画的全部入口:
| 闭包 | 默认参数 | 生效于哪些方法 |
|---|---|---|
animate | 0.5 秒弹簧,damping = 1(无回弹) | show/hide/set(_:hidden:animated:),以及带动画的remove |
scrollAnimate | 0.75 秒弹簧,damping = 0.7,初始速度 = 0.25 | scrollTo(viewController:) |
💡 两个默认实现defaultAnimate、defaultScrollAnimate都定义在ScrollingStackViewController/Classes/ScrollingStackViewController.swift(第 49–77 行),而animate和scrollAnimate只是两个公开属性,初始值指向默认实现——所以随时可以直接赋值替换。
两个闭包的签名一致:传入“要执行的动画块”和一个completion回调(Bool表示动画是否完成),你只需要用自己喜欢的UIView.animate(...)方式把它们跑起来。
覆盖 animate:给分区显示/隐藏加上弹性回弹
想让show(vc)/hide(vc)出现“boing”的回弹感,把dampingRatio调到 1 以下即可:
animate = { animations, completion in UIView.animate(withDuration: 0.8, dampingRatio: 0.6, initialSpringVelocity: 0.5, options: [], animations: animations, completion: completion) }参数提示:dampingRatio = 1表示完全不回弹;数值越小,弹跳越明显。initialSpringVelocity越大,起手越有“甩出去”的感觉。
覆盖 scrollAnimate:换掉“滚动到指定分区”的动画
程序化滚动(点击后跳到第 N 个分区)走的是scrollAnimate,改animate对它无效:
scrollAnimate = { animations, completion in UIView.animate(withDuration: 1.0, dampingRatio: 0.7, initialSpringVelocity: 0.25, options: [], animations: animations, completion: completion) }如果只想简单改时长,官方 README 给的最简写法也完全够用:
scrollAnimate = { animations, completion in UIView.animate(withDuration: 1, animations: animations, completion: completion) }弹性动画参数建议与覆盖时机
| 参数 | 弹性手感建议区间 | 说明 |
|---|---|---|
duration | 0.6 ~ 1.0 秒 | 太短会让回弹显得生硬 |
dampingRatio | 0.5 ~ 0.7 | 越接近 1 回弹越弱 |
initialSpringVelocity | 0.25 ~ 0.5 | 决定起始的“冲刺感” |
✅推荐覆盖时机:在你继承 ScrollingStackViewController 的子类viewDidLoad()里、super.viewDidLoad()之后赋值,然后再add(viewController:)添加分区:
override func viewDidLoad() { super.viewDidLoad() animate = { animations, completion in UIView.animate(withDuration: 0.8, dampingRatio: 0.6, initialSpringVelocity: 0.5, options: [], animations: animations, completion: completion) } scrollAnimate = { animations, completion in UIView.animate(withDuration: 1.0, dampingRatio: 0.7, initialSpringVelocity: 0.25, options: [], animations: animations, completion: completion) } add(viewController: child1) }官方示例工程Example/ScrollingStackViewController/ViewController.swift展示了添加分区、设置spacingColor、调用scrollTo的完整用法,可对照阅读。
常见坑与排查清单
- ⚠️
show/hide传animated: false时不会走animate,而是直接改alpha和isHidden——看不出动画效果时先检查这里。 - ⚠️
scrollTo只认scrollAnimate;只改animate不会让滚动变弹。 - 💡
scrollTo在内容高度尚未确定时会自动延迟到布局完成后再执行,不需要手动强制 layout。 - 💡 闭包第二个参数
completion(Bool)用于判断动画是否真正完成,适合串联“滚动到位后再高亮”等后续逻辑。
相关资料速查
- 核心实现(闭包定义与
scrollTo逻辑):ScrollingStackViewController/Classes/ScrollingStackViewController.swift - 可运行的演示子类:
Example/ScrollingStackViewController/ViewController.swift - 用法与安装说明(含动画覆盖示例):
README.md
【免费下载链接】ScrollingStackViewControllerA view controller that uses root views of child view controllers as views in a UIStackView.项目地址: https://gitcode.com/gh_mirrors/sc/ScrollingStackViewController
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考