Search code examples
swiftuiswiftui-animation

swiftui transition not work on extracted view


I just build a small pop up with .spring() animation that I want to use later in my app, but the back transition is not smooth. It simply disappear from the hierarchy. So here is my code:

struct TestPopUp: View {


@State var screen: Bool = false

var body: some View {
        ZStack {
            Color.white
                .edgesIgnoringSafeArea(.all)
            
            VStack {
                Button("Click") {
                    withAnimation(.spring()) {
                        screen.toggle()
                    }
                   
                }
                .font(.largeTitle)

                if screen {
                    NewScreen(screen: $screen)
                        .padding(.top, 300)
                        .transition(.move(edge: .bottom))
                }
}

struct NewScreen: View {
    
    @Binding var screen: Bool
    
    var body: some View {
    ZStack(alignment: .topLeading) {
            Color.black
                .edgesIgnoringSafeArea(.all)
            
            Button {
                screen.toggle()
            } label: {
                Image(systemName: "xmark")
                    .foregroundColor(.white)
                    .font(.largeTitle)
                    .padding(20)
            }

            
        }
    }
}

Transition popup

As you can see in the video, the view disappears. But I want the same transition backwards.


Solution

  • You have to animate the transition both ways, in and out. Therefore, NewScreen becomes:

    struct NewScreen: View {
        
        @Binding var screen: Bool
        
        var body: some View {
            ZStack(alignment: .topLeading) {
                Color.black
                    .edgesIgnoringSafeArea(.all)
                
                Button {
                    withAnimation(.spring()) { // Animate here!
                        screen.toggle()
                    }
                } label: {
                    Image(systemName: "xmark")
                        .foregroundColor(.white)
                        .font(.largeTitle)
                        .padding(20)
                }
            }
        }
    }