SwiftUI双层粘性头部实现问题求助
实现双层粘性头部(红色头部锚定绿色头部下方)
要让红色的SecondHeaderView始终固定在绿色HeaderView的下方,同时保证SecondView单独使用时自身的粘性头部正常工作,可以通过以下方式调整代码:
修改后的完整代码
struct ContentView: View { @State private var headerHeight: CGFloat = 0 var body: some View { ScrollView(showsIndicators: false) { LazyVStack(spacing: 0, pinnedViews: .sectionHeaders) { Section { SecondView(topOffset: headerHeight) } header: { HeaderView() .background( GeometryReader { geo in Color.clear .onAppear { headerHeight = geo.size.height } } ) } } } } } struct HeaderView: View { var body: some View { Rectangle() .fill(.green) .frame(height: 50) } } struct SecondView: View { let topOffset: CGFloat // 接收外部传递的头部高度,单独使用时传0 var body: some View { LazyVStack(spacing: 0, pinnedViews: .sectionHeaders) { Section { VStack { ForEach(0..<20) { index in ItemView(index: index) } } } header: { SecondHeaderView() .offset(y: topOffset) .padding(.top, -topOffset) } } } } struct SecondHeaderView: View { var body: some View { Rectangle() .fill(.red) .frame(height: 60) } } struct ItemView: View { let index: Int var body: some View { VStack { Text("Item \(index)") .padding() } .frame(height: 80) .background(.gray) } } #Preview { // 测试ContentView ContentView() // 测试单独使用SecondView // SecondView(topOffset: 0) }
关键调整说明
- 获取绿色头部高度:在
HeaderView的背景中嵌入GeometryReader,获取其高度并保存到headerHeight状态变量中。 - 传递偏移量给SecondView:将绿色头部的高度作为
topOffset参数传递给SecondView,当SecondView单独使用时,传入0即可保持原有粘性效果。 - 调整红色头部的固定位置:给
SecondHeaderView添加offset(y: topOffset)让它向下偏移,同时用padding(.top, -topOffset)抵消偏移带来的布局空隙,确保列表内容的位置不受影响。
这样滚动时,红色头部会始终固定在绿色头部的下方,同时SecondView单独使用时,粘性头部会正常固定在屏幕顶部。
内容的提问来源于stack exchange,提问作者soleil
相关产品推荐
相关产品推荐

