SwiftUI 滚动视图粘性标题而不使用列表

问题描述 投票:0回答:1

我一直在与

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 中所有其他内容的顶部,以便其他内容在其下方滚动。

swiftui swiftui-scrollview
1个回答
0
投票

尝试使用带有部分和粘性标题的

LazyVStack

  • 第一部分包含视图 A,没有标题。
  • 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)
        }
    }
}

Animation

© www.soinside.com 2019 - 2024. All rights reserved.