This is a toy example of a problem I'm facing. I have a custom tab bar (blue) sitting at the bottom of my first view (red) and the tab bar is hidden when a detail view (yellow) is pushed on to the navigation stack.
The issue is that the detail view starts off at the same height as that of the first view and once the transition is complete, revises it's height without any transition. How can I make the detail view animate (grow in height) with the bottom bar. If that is not possible, could I make the detail view revise it's height before the start of the transition and not after?
struct ContentView: View {
@State var showDetail: Bool = false
var body: some View {
VStack {
NavigationStack {
ZStack {
Color.red
Button {
withAnimation { showDetail = true }
} label: {
Text("Detail View")
.font(.largeTitle)
.foregroundStyle(Color.white)
}
}
.background {
NavigationLink(destination: Color.yellow, isActive: $showDetail) {
EmptyView()
}
}
}
Color.blue.frame(height: showDetail ? 0 : 150)
}
}
}
#Preview {
ContentView()
}
It helps to show the custom tab bar using .safeAreaInset
(which is a good way to show it anyway). Also:
It seems that the ZStack
goes behind this inset, so you might want to add .safeAreaPadding
to the ZStack
to compensate.
If you add an .animation
modifier to the custom tab bar then the transition back to the parent view can be animated too.
VStack {
NavigationStack {
ZStack {
// ...
}
.background {
// ...
}
.safeAreaPadding(.bottom, 150)
}
.safeAreaInset(edge: .bottom) {
Color.blue.frame(height: showDetail ? 0 : 150)
.animation(.easeInOut, value: showDetail)
}
}