无需使用 LazyVStack 在 SwiftUI 上固定视图
PinnedScrollView
PinnedScrollView 是一个轻量级 SwiftUI 库,只需添加即可在滚动视图中固定任何视图,例如标题,而无需使用 LazyVStack
和 Section
。
用法
var body: some View {
ScrollView {
VStack(spacing: 0) {
ForEach(0..<20) { _ in
Text("Header")
.pinned() // 1
Text("Some content text")
}
}
}
.pinnedScrollView() // 2
}
- 将
.pinned()
修饰符添加到想要在滚动视图中固定的视图 - 将
.pinnedScrollView()
修饰符添加到相应的滚动视图
就是这样!
可选观察
如果想要在固定状态发生改变时收到通知,还可以向 pinned
修饰符提供可选闭包 onReachedTop: (Bool) -> ()
。
@State private var isHeaderReachedTop = false
// ...
Text("Header" + (isHeaderReachedTop ? " Reached" : ""))
.pinned { isReachedTop in
isHeaderReachedTop = isReachedTop
}
限制
PinnedScrollView 需要 iOS/iPadOS 14.0。
PinnedScrollView 只支持垂直 ScrollView
,不支持水平 ScrollView
或 List
视图。
安装
使用 Swift Package Manager 将 PinnedScrollView 添加到项目中。
https://github.com/Lumisilk/PinnedScrollView.git
许可证
此软件包在 MIT 开源许可证下获得许可。
灵感
PinnedScrollView 的实现灵感来自 objc.io 的课程 针对滚动视图的粘性标题。不同于 objc.io 使用 PreferenceKey
来协调标题的框架的初始实现,这可能导致性能瓶颈,PinnedScrollView 使用 onChange
来有效记录标题的框架。
此外,PinnedScrollView 使用 Combine 的 debounce
和发布者来最小化标题的正文的重新评估计数,旨在优化性能。
特别感谢 @auramagi 提供算法建议。