iosswiftui

Synchronise transition animation inside and outside a NavigationView


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?

enter image description here

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()
}

Solution

  • It helps to show the custom tab bar using .safeAreaInset (which is a good way to show it anyway). Also:

    VStack {
        NavigationStack {
            ZStack {
                // ...
            }
            .background {
                // ...
            }
            .safeAreaPadding(.bottom, 150)
        }
        .safeAreaInset(edge: .bottom) {
            Color.blue.frame(height: showDetail ? 0 : 150)
                .animation(.easeInOut, value: showDetail)
        }
    }
    

    Animation