Tenho lutado GeometryReader
e .onChange(of: geo.frame(in: .global).minY)
tentado por muito tempo fazer isso funcionar sem muito sucesso. Considere o seguinte:
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) { 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)
}
}
}
}
}
O objetivo é fazer com que a View B fique no topo (logo abaixo da barra de navegação) quando você rolar a view para cima e, claro, tome seu lugar normal na scrollview quando você rolar de volta para baixo. Eu sei que você pode fazer cabeçalhos fixos com List
e Sections
mas isso não atende às minhas necessidades porque note que a View B (a view fixa) não é necessariamente o primeiro item na scrollview.
Observe também que a Exibição B deve permanecer no topo de todo o outro conteúdo no VStack para que o outro conteúdo role abaixo dela.
Tente usar um
LazyVStack
com seções e cabeçalhos fixados:ForEach
como conteúdo principal e a Visualização B como cabeçalho.