ScrollingStackViewController API速查表:add、insert、show、hide、remove、scrollTo全方法一篇讲透
【免费下载链接】ScrollingStackViewControllerA view controller that uses root views of child view controllers as views in a UIStackView.项目地址: https://gitcode.com/gh_mirrors/sc/ScrollingStackViewController
ScrollingStackViewController 是 Just Eat 团队开源的 iOS 滚动视图控制器库,它把子视图控制器放进 UIStackView 中做垂直滚动布局。本文是它的 API 速查表:add、insert、show、hide、remove、scrollTo 六大核心方法一次讲透,并附完整参数对照表,帮你在 10 分钟内掌握全部用法。
它解决什么问题?
🧩 用UITableViewController展示"数量有限、但每段都很复杂"的内容时,数据源模式有点杀鸡用牛刀,索引管理也容易出 bug。
ScrollingStackViewController 的思路更直接:
- 每一段内容都是一个独立的子视图控制器,各自管理自己的逻辑;
- 布局交给
UIStackView,滚动交给UIScrollView; - 你只需要"添加、显示、隐藏、移除、滚动",其余脚手架库都帮你搭好了。
核心实现只有一个文件:ScrollingStackViewController.swift,支持 iOS 12 及以上。下面逐一看这 6 个方法。
add:把子控制器追加到列表末尾
最简单的方式,把子控制器直接加到栈的最后:
add(viewController: childVC)它也带一个可选的edgeInsets参数,给子视图四周加内边距(内部会自动包一层容器视图):
add(viewController: cardVC, edgeInsets: UIEdgeInsets(top: 20, left: 40, bottom: 20, right: 40))示例工程 ViewController.swift 里就用add一次性添加了 10 个彩色列,其中 6 个带内边距。
insert:用 Position 精确控制插入位置
✨insert是add的加强版,通过Position枚举指定插入位置,共 5 种:
| 位置 | 含义 |
|---|---|
.start | 插到最前面 |
.end | 插到最后(默认值) |
.index(2) | 插到第 2 个索引处(越界会自动收敛到末尾) |
.after(viewController: A) | 插在控制器 A 的后面 |
.before(viewController: B) | 插在控制器 B 的前面 |
最常用的两行写法:
insert(viewController: newVC, at: .index(1)) insert(viewController: newVC, edgeInsets: insets, at: .after(existingVC))⚠️ 小提示:Position定义在源文件 ScrollingStackViewController.swift,insert的完整逻辑在 第 147-203 行。带edgeInsets插入时,子视图会多包一层容器,后续做显隐控制时建议配合show/hide使用。
show 和 hide:有动画的显示与隐藏
👀 这两个方法不改变列表结构,只改可见性,是动态 UI 的主力:
show(viewController: tipVC) // 显示(默认带动画) hide(viewController: tipVC) // 隐藏(默认无动画) show(tipVC, animated: true) { done in ... } // 带完成回调注意两者默认值不对称:show默认动画打开,hide默认动画关闭。它们内部统一走set(_:hidden:animated:)方法,用 alpha 淡入淡出实现过渡;对未添加进列表的控制器调用会安全地返回false。
还有一个"二合一"重载,适合"没有就先插入、有就直接显示"的场景:
show(bannerVC, insertIfNeededWith: (position: .end, insets: .zero), animated: true)如果控制器还不在层级里,它会按你给的position和insets自动插入;已经在则只做显示。对应测试用例见 ScrollingStackViewInsertionLocationTests.swift。
remove:真正移除并清理父级关系
hide只是隐藏,remove才是从列表里彻底拿走——同时解除子控制器与父级的关系:
remove(viewController: oldVC) // 直接移除 remove(viewController: oldVC, animated: true) { done in ... }带animated: true时,会先执行一次hide的淡出动画,动画结束后才真正移除,视觉更自然。
💡 官方建议:如果某些段落的显隐很频繁,不如一开始就add好,之后只show/hide,省去反复增删的开销。
scrollTo:平滑滚动到指定子控制器
scrollTo(viewController: detailVC) { print("滚动完成") }几个值得知道的细节:
- 滚动用的是弹簧动画(默认 0.75 秒、阻尼 0.7),手感柔和;
- 如果布局还没就绪,库会自动等
viewDidLayoutSubviews完成后再滚,不用你手动处理时序; - 对带
edgeInsets的容器子视图,滚动定位会自动换算成容器的位置,偏移量始终准确(参考 ScrollingStackViewTests.swift 中的滚动偏移测试)。
API 全方法速查表
| 方法 | 作用 | 默认行为 |
|---|---|---|
add(viewController:) | 追加到末尾 | 无内边距 |
insert(viewController:edgeInsets:at:) | 按Position插入 | position默认.end |
show(_:animated:) | 淡入显示 | 默认动画 = true |
hide(_:animated:) | 淡出隐藏 | 默认动画 = false |
remove(_:animated:) | 移除并解绑 | 默认动画 = false |
scrollTo(viewController:) | 平滑滚动定位 | 弹簧动画,可回调 |
show(_:insertIfNeededWith:) | 不存在则先插入再显示 | 动画默认打开 |
进阶:自定义动画与外观属性
库把scrollView、stackView、stackViewBackgroundView都暴露成了公开属性,常用调优只有几个属性:
spacingColor = .lightGray // 段与段之间的分隔线颜色 stackView.spacing = 0.5 // 分隔线粗细间隔 borderWidth = 1 // 整体边框宽度 borderColor = .darkGray // 整体边框颜色想换动画风格?替换两个闭包即可:
animate = { animations, completion in UIView.animate(withDuration: 1, animations: animations, completion: completion) }animate管显隐过渡,scrollAnimate管滚动过渡。
3 个新手最容易踩的坑 📌
- 子控制器必须能"自撑高度":给它加一个垂直方向的约束(如固定高度或内容撑开),否则在 StackView 里会塌成 0 高;
- 带
edgeInsets添加的子视图外面多一层容器,做显隐时优先用show/hide; show不等于add:对一个从未添加过的控制器直接show是无效操作,需要配合insertIfNeededWith重载才会自动插入。
获取与体验项目
通过 CocoaPods 安装只需一行:
pod "ScrollingStackViewController"也支持 Swift Package Manager(配置见项目根目录的 Package.swift)。想浏览示例工程和单元测试(Tests 目录),可克隆仓库:
git clone https://gitcode.com/gh_mirrors/sc/ScrollingStackViewController跑起来Example工程,点顶部按钮就能看到hide/show切换和scrollTo滚动的真实效果——配合本文的速查表,ScrollingStackViewController 的全部方法你都已经掌握了。
【免费下载链接】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),仅供参考