Home > Software design >  How can I get a different transition animation for insertion & removal?
How can I get a different transition animation for insertion & removal?

Time:07-20

I can specify a different transition for when the view is inserted vs removed:

.transition(
    .asymmetric(
        insertion: .move(edge: .leading)
        removal: .move(edge: .trailing)
    )
)

This works fine. However I would like it so ease in quickly, when it is added, and ease out slowly when removed. The following does not appear to do anything, despite compiling just fine.

.transition(
    .asymmetric(
        insertion: .move(edge: .leading)
            .animation(.easeIn(duration: 2)),
        removal: .move(edge: .trailing)
            .animation(.easeOut(duration: 5))
    )
)

Am I misunderstanding the use of .animation as a modifier on transitions?

Demo code:

struct TestView: View {
    @State private var showDetails = false

    var body: some View {
        VStack {
            Button("Press to show details") {
                withAnimation {
                    showDetails.toggle()
                }
            }

            if showDetails {
                Text("Details go here.")
                    .background(Color.blue)
                    .transition(
                        .asymmetric(
                            insertion: .move(edge: .leading)
                                .animation(.easeIn(duration: 5)),
                            removal: .move(edge: .trailing)
                                .animation(.easeOut(duration: 5))
                        )
                    )
            }
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
    }
}

CodePudding user response:

Here is something that I found to work. Use a different withAnimation call with each direction:

Button("Press to show details") {
    if !showDetails {
        withAnimation(.easeIn(duration: 2)) {
            showDetails.toggle()
        }
    } else {
        withAnimation(.easeOut(duration: 5)) {
            showDetails.toggle()
        }
    }
}

CodePudding user response:

Explicit animation can be provided right in withAnimation call, so here is a solution.

demo

Tested with Xcode 13.4 / iOS 15.5

Button("Press to show details") {
    withAnimation(!showDetails ? .easeIn(duration: 2) : .easeOut(duration: 5)) {
        showDetails.toggle()
    }
}

if showDetails {
    Text("Details go here.")
        .background(Color.blue)
        .transition(
            .asymmetric(
                insertion: .move(edge: .leading),
                removal: .move(edge: .trailing)
            )
        )
}

Test code on GitHub

  • Related