我一直在与
GeometryReader
和 .onChange(of: geo.frame(in: .global).minY)
斗争很长时间,试图让它发挥作用,但没有取得很大成功。考虑以下几点:
struct TestScreen: View {
var body: some View {
NavigationStack {
ScrollView {
VStack {
Text("View A")
.frame(height: 50)
.frame(maxWidth: .infinity)
.background(.green)
Text("View B - Sticky")
.frame(height: 50)
.frame(maxWidth: .infinity)
.background(.blue)
ForEach(0..<15, id: \.self) { i in
Text("View \(i)")
.frame(height: 50)
.frame(maxWidth: .infinity)
.background(Color.red)
}
}
}
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.clear, for: .navigationBar)
.toolbar {
ToolbarItem(placement: .principal) {
Text("Testing")
.foregroundColor(.purple)
}
}
}
}
}
目标是当您向上滚动视图时,使视图 B 粘在顶部(就在导航栏下方),当然,当您向下滚动时,它在滚动视图中占据正常位置。我知道您可以使用
List
和 Sections
做粘性标题,但这不适合我的需求,因为请注意,视图 B(粘性视图)不一定是滚动视图中的第一项。
另请注意,视图 B 必须位于 VStack 中所有其他内容的顶部,以便其他内容在其下方滚动。
尝试使用带有部分和粘性标题的
LazyVStack
:
ForEach
可以位于第 2 部分中,视图 B 位于粘性标题中。ScrollView {
LazyVStack(pinnedViews: .sectionHeaders) {
Section {
Text("View A")
.frame(height: 50)
.frame(maxWidth: .infinity)
.background(.green)
}
Section {
ForEach(0..<15, id: \.self) { i in
Text("View \(i)")
.frame(height: 50)
.frame(maxWidth: .infinity)
.background(Color.red)
}
} header: {
Text("View B - Sticky")
.frame(height: 50)
.frame(maxWidth: .infinity)
.background(.blue)
}
}
}