No meu aplicativo, tenho ScrollView
uma subvisão estática como cabeçalho e uma LazyVStack
com vários elementos preenchidos com dados do modelo de visualização. Além disso, se esses dados "dinâmicos" estiverem vazios, em vez de LazyVStack
, mostro uma visualização de espaço reservado. Aqui está uma estrutura simplificada da visualização:
var body: some View {
GeometryReader { geometry in
ScrollView {
HStack(spacing: .zero) {
Text("This is my greeting to you")
Spacer()
}
if greetings.isEmpty {
PlaceholderView()
.frame(height: geometry.size.height)
} else {
LazyVStack {
ForEach(greetings, id: \.self) {
Text($0)
}
}
}
}
}
}
private var greetings: [String]
PlaceholderView
:
VStack {
Image(systemName: "hand.wave")
Text("Hello world!")
}
Quero PlaceholderView
ser exibido no meio do espaço disponível (ou seja, neste caso, toda a altura da tela menos a altura da HStack
parte superior). Muitas perguntas semelhantes aqui sugerem o uso GeometryReader
, mas não ajuda neste caso :
GeometryReader { geometry in
ScrollView {
HStack(spacing: .zero) {
Text("This is my greetings to you")
Spacer()
}
if greetings.isEmpty {
ExampleView()
.frame(height: geometry.size.height)
} else {
LazyVStack {
ForEach(greetings, id: \.self) {
Text($0)
}
}
}
}
}
Usar o código acima PlaceholderView
ocupa mais espaço do que o necessário. No meu caso, deveria ser algo como geometry.size.height - hStackHeight
:

Existe uma maneira de obter PlaceholderView
exatamente a altura da tela menos HStack
a altura de? Qualquer orientação é muito apreciada.
Se você quebrar
PlaceholderView
em um segundoGeometryReader
, poderá usá-lo para obter o deslocamento vertical no espaço de coordenadas global (sendo este o qualhStackHeight
você se referiu). Isso pode ser subtraído da altura:A única coisa com esta solução é que a altura aumenta quando a mensagem no topo é afastada usando uma ação de rolagem. Isso significa que a mensagem e o espaço reservado não se movem em sincronia, o que parece um pouco estranho. Então eu provavelmente optaria por suprimir
ScrollView
quando não houver saudações para exibir, conforme resposta de superpuccio.EDITAR Finalmente resolvi. Um adicional
VStack
é necessário dentro do arquivoScrollView
. Então o ajuste pode usar o espaço de coordenadas do arquivoVStack
. Isso resolve o problema do movimento de rolagem não sincronizado:Se você não precisa que o espaço reservado salte para cima e para baixo, evite usar a
ScrollView
caso não haja dados para mostrar. Quero dizer:O resultado é: