SwiftUI:匹配的几何效果不起作用

SwiftUI: Matched Geometry Effect doesn't work

我正在制作使用匹配几何效果的应用程序。它匹配嵌入在两个不同视图中的两个矩形。它没有按预期工作。请帮我。 这是测试视图:

struct ContentViewTest: View {
    @State var details = false
    @Namespace var animation
    
    var body: some View {
        ZStack {
            if !details {
                TestView2(details: $details, anim: animation)
            }
            if details {
                TestView1(details: $details, anim: animation)
            }
        }
    }
}

这是 TestView1:

struct TestView1: View {
    @Binding var details: Bool
    var anim: Namespace.ID
    var body: some View {
        ZStack{
            Color.gray.ignoresSafeArea()
            Color.red.frame(width: 300, height: 700)
                .matchedGeometryEffect(id: "id1", in: anim)
                .onTapGesture {
                    withAnimation {
                        details = false
                    }
                }
        }
    }
}

这是 TestView2:

struct TestView2: View {
    @Binding var details: Bool
    var anim: Namespace.ID
    var body: some View {
        ZStack{
            Color.green.ignoresSafeArea()
            Color.red.frame(width: 200, height: 200)
                .matchedGeometryEffect(id: "id1", in: anim)
                .onTapGesture {
                    withAnimation {
                        details = true
                    }
                }
        }
    }
}

这是解决您的问题的方法,在正确的位置使用 transition 和 matchedGeometryEffect:

struct ContentView: View {
    @State var details = false
    @Namespace var namespace
    private let id: String = "myID"
    var body: some View {
        
        if (details) {
            TestView1(details: $details, id: id, namespace: namespace)
        }
        else {
            TestView2(details: $details, id: id, namespace: namespace)
        }
        
    }
}


struct TestView1: View {
    @Binding var details: Bool
    let id: String
    var namespace: Namespace.ID
    var body: some View {
        
        ZStack {
          
            Color.gray.ignoresSafeArea()
            
            Color.red
                .matchedGeometryEffect(id: id, in: namespace)
                .transition(.scale(scale: 1.0))
                .frame(width: 300, height: 700)
                .onTapGesture {
                    withAnimation {
                        details = false
                    }
                }
            
        }

    }
}

struct TestView2: View {
    @Binding var details: Bool
    let id: String
    var namespace: Namespace.ID
    var body: some View {
        ZStack {
            Color.green.ignoresSafeArea()
            
            Color.red
                .matchedGeometryEffect(id: id, in: namespace)
                .transition(.scale(scale: 1.0))
                .frame(width: 200, height: 200)
                .onTapGesture {
                    withAnimation {
                        details = true
                    }
                }
        }
  
    }
}

只需添加 properties 位置(在两个匹配的视图中),如下所示

Color.red.frame(width: 300, height: 700)
    .matchedGeometryEffect(id: "id1", in: anim, properties: .position)  // << here !!

或(取决于您想要达到的效果)更改修饰符的顺序(对于两个视图),例如

Color.red
    .matchedGeometryEffect(id: "id1", in: anim) // << here !! 
    .frame(width: 300, height: 700)

测试 Xcode 13.2 / iOS 15.2