Lorenzo Fiamingo
Lorenzo Fiamingo

Reputation: 4079

matchedGeometryEffect doesn't work properly

Using the last example from this Hacking with swift article you'll see that the text is not well animated when isZoomed is toggled to false. I can't understand why...

struct ContentView: View {
    @Namespace private var animation
    @State private var isZoomed = false

    var frame: CGFloat {
        isZoomed ? 300 : 44
    }

    var body: some View {
        VStack {
            Spacer()

            VStack {
                HStack {
                    RoundedRectangle(cornerRadius: 10)
                        .fill(Color.blue)
                        .frame(width: frame, height: frame)
                        .padding(.top, isZoomed ? 20 : 0)

                    if isZoomed == false {
                        Text("Taylor Swift – 1989")
                            .matchedGeometryEffect(id: "AlbumTitle", in: animation)
                            .font(.headline)
                        Spacer()
                    }
                }

                if isZoomed == true {
                    Text("Taylor Swift – 1989")
                        .matchedGeometryEffect(id: "AlbumTitle", in: animation)
                        .font(.headline)
                        .padding(.bottom, 60)
                    Spacer()
                }
            }
            .onTapGesture {
                withAnimation(.spring()) {
                    self.isZoomed.toggle()
                }
            }
            .padding()
            .frame(maxWidth: .infinity)
            .frame(height: isZoomed ? 400 : 60)
            .background(Color(white: 0.9))
        }
    }
}

Upvotes: 1

Views: 624

Answers (1)

Asperi
Asperi

Reputation: 257729

Wrap every removable part into own stack, the container will animation removing views properly.

Tested with Xcode 12.1 / iOS 14.1

VStack {
    HStack {
        RoundedRectangle(cornerRadius: 10)
            .fill(Color.blue)
            .frame(width: frame, height: frame)
            .padding(.top, isZoomed ? 20 : 0)
        
        HStack {                         // << here !!
            if isZoomed == false {
                Text("Taylor Swift – 1989")
                    .matchedGeometryEffect(id: "AlbumTitle", in: animation)
                    .font(.headline)
                Spacer()
            }}
    }
    VStack {                             // << here !!
        if isZoomed == true {
            Text("Taylor Swift – 1989")
                .matchedGeometryEffect(id: "AlbumTitle", in: animation)
                .font(.headline)
                .padding(.bottom, 60)
            Spacer()
        }
    }
}

Upvotes: 1

Related Questions