I am trying to have a ScrollView of content and when tapping on a row, I want the row's height (bottom and top) to animate to take the full screen height. I tried the following with no success:
struct ContentView: View {
@State private var selectedRow: Int? = nil
var body: some View {
ScrollView {
ForEach(0..<10, id: \.self) { row in
HStack {
Text("Row \(row)")
}
.frame(minHeight: self.selectedRow == row ? 0 : 50, maxHeight: self.selectedRow == row ? .infinity : 50)
.animation(.easeInOut(duration: 1))
.onTapGesture {
self.selectedRow = row
}
}
}
}
}
This doesn't work like I was hoping and doesn't take the full screen height.
Is this the wrong approach? Is it better to make it navigate to a new view and have it animate into the new view?
CodePudding user response:
Scroll views always try to size the content with the smallest height (in the case of a vertical scroll view). If they used the max size, and it was .infinite
, they would be infinitely long.
Instead you should use a GeometryReader
to get the size of the view that contains the scroll view, and use the explicit height of the size of the scroll view.
import SwiftUI
struct ContentView: View {
@State private var selectedRow: Int? = nil
var body: some View {
GeometryReader { reader in
ScrollView {
ForEach(0..<10, id: \.self) { row in
HStack {
Text("Row \(row)")
}
.frame(height: selectedRow == row ? reader.size.height : 50)
.animation(.easeInOut(duration: 1))
.onTapGesture {
self.selectedRow = row
}
}
}
}
}
}