ios – Can a SwiftUI matchedGeometryEffect animation be mixed with a transition?


I would like to exchange the default transition (AnyTransition.opacity) with one other transition for a view that additionally has a matchedGeometryEffect() modifier utilized. I’ve tried a pair completely different strategies, however none of them appear to perform this.

First, here is the matchedGeometryEffect by itself. The ItemView “strikes” from one container to a different, utilizing the default animation.

struct ContentView: View {
    @Namespace personal var itemMovement
    @State personal var isInFirst = true
    
    var physique: some View {
        VStack {
            Textual content("First Container")
            HStack {
                if isInFirst {
                    ItemView()
                        .matchedGeometryEffect(id: "merchandise", in: itemMovement)
                }
            }
            .padding()
            .border(.crimson)
            
            Textual content("Second Container")
            HStack {
                if !isInFirst {
                    ItemView()
                        .matchedGeometryEffect(id: "merchandise", in: itemMovement)
                }
            }
            .padding()
            .border(.crimson)
            
            Button("Transfer Merchandise") {
                withAnimation {
                    isInFirst.toggle()
                }
            }
        }
    }
}

struct ItemView: View {
    var physique: some View {
        Circle()
            .foregroundStyle(.blue)
            .body(width: 100, top: 100)
    }
}

Implementation with default transitions and matchedGeometryEffect, Circle view animates from one container to the other

Wanting intently on the Circle, you may see that the colour will get lighter on the center of the animation. I imagine this the impact of the default transition, AnyTransition.opacity. In an try to take away that transition, I attempted to explicitly add an AnyTransition.id on the Circle view.

struct ContentView: View {
    @Namespace personal var itemMovement
    @State personal var isInFirst = true
    
    var physique: some View {
        VStack {
            Textual content("First Container")
            HStack {
                if isInFirst {
                    ItemView()
                        .transition(.id) // <-- right here
                        .matchedGeometryEffect(id: "merchandise", in: itemMovement)
                }
            }
            .padding()
            .border(.crimson)
            
            Textual content("Second Container")
            HStack {
                if !isInFirst {
                    ItemView()
                        .transition(.id) // <-- right here
                        .matchedGeometryEffect(id: "merchandise", in: itemMovement)
                }
            }
            .padding()
            .border(.crimson)
            
            Button("Transfer Merchandise") {
                withAnimation {
                    isInFirst.toggle()
                }
            }
        }
    }
}

Nevertheless the consequence looks like the Circle view is now not animating with the matchedGeometryEffect. I’ve tried a pair variations, resembling putting the .transition() modifier after the .matchedGeometryEffect() modifier, and utilizing the .transition() modifier on just one view at a time – hoping to grasp why this leaping to the ultimate place happens and formulate a brand new resolution. I have never figured it out but.

Can anybody assist me work out methods to mix a transition with the matchedGeometryEffect? Outdoors of this simplified instance, I am hoping to create a customized transition, based mostly on an animatable view modifier, which internally applies a .rotation3DEffect() to the view.

Adding an explicit transition, the Circle view jumps to the final position instead of animating

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles