首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何正确使用matchedGeometry?

如何正确使用matchedGeometry?
EN

Stack Overflow用户
提问于 2020-10-28 21:51:52
回答 2查看 3.8K关注 0票数 12

当我使用匹配的几何视图修饰符时,我总是收到警告。

Multiple inserted views in matched geometry group Pair<String, ID>(first: "id1", second: SwiftUI.Namespace.ID(id: 8)) have isSource: true, results are undefined.

当动画仍然有效时,我想了解为什么我会收到这个警告,以及如何解决这个问题。

这是我制作的动画,有什么想法怎么摆脱警告吗?

使用以下代码

代码语言:javascript
运行
复制
struct ContentView: View {
    @State var details = false
    @Namespace var animation
    
    var body: some View {
        ZStack {
            HStack {
                Rectangle()
                    .frame(width: 100, height: 100)
                    .matchedGeometryEffect(id: "id1", in: animation)
                    .onTapGesture {
                        withAnimation {
                            details.toggle()
                        }
                    }
                
                
                Spacer()
            }
            .zIndex(1)
            
            if details == true {
                AnotherView(details: $details, animation: animation)
                    .zIndex(2)
            }
        }
    }
}


struct AnotherView: View {
    @Binding var details: Bool
    var animation: Namespace.ID
    
    var body: some View {
        ZStack {
            Color.red
            
            Rectangle()
                .frame(width: 300, height: 300)
                .matchedGeometryEffect(id: "id1", in: animation)
                .onTapGesture {
                    withAnimation {
                        details.toggle()
                    }
                }
        }
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-10-28 22:18:41

问题是同时在屏幕上有两个视图(即使第二个视图包含第一个视图,第一个视图仍然在屏幕上)。使用.matchedGeometryEffect,一个视图在逻辑上取代了另一个视图,因此在绘制第二个视图时需要删除第一个视图。您可以通过只在Rectangle时绘制第一个!details来修复这个问题。

另外,为了更干净的效果,我将.matchedGeometryEffect移动到Rectangles的第一个修饰符。

代码语言:javascript
运行
复制
struct ContentView: View {
    @State var details = false
    @Namespace var animation
    
    var body: some View {
        ZStack {
            HStack {
                if !details {
                    Rectangle()
                        .matchedGeometryEffect(id: "id1", in: animation)
                        .frame(width: 100, height: 100)
                        .onTapGesture {
                            withAnimation {
                                details.toggle()
                            }
                        }
                }
                
                
                Spacer()
            }
            .zIndex(1)
            
            if details {
                AnotherView(details: $details, animation: animation)
                    .zIndex(2)
            }
        }
    }
}


struct AnotherView: View {
    @Binding var details: Bool
    var animation: Namespace.ID
    
    var body: some View {
        ZStack {
            Color.red
            
            Rectangle()
                .matchedGeometryEffect(id: "id1", in: animation)
                .frame(width: 300, height: 300)
                .onTapGesture {
                    withAnimation {
                        details.toggle()
                    }
                }
        }
    }
}

.matchedGeometryEffect Documentation状态(粗体后加):

如果在同一事务中插入另一个具有相同键的视图,则系统将在窗口空间内插入其框架矩形,使之看起来有一个视图从其旧位置移动到其新位置。

通常的转换机制定义了在过渡期间如何呈现这两个视图(例如,淡入/退出、缩放等),matchedGeometryEffect()修饰符只安排要链接视图的几何图形,而不是它们的呈现。

如果在具有isSource = true的组中当前插入的视图的数量并不完全是一个未定义的结果,因为它不清楚哪个是源视图。

票数 16
EN

Stack Overflow用户

发布于 2020-10-29 05:13:04

下面的变体也适用于预览版(由@vacawama提出,只是以防万一)。

用Xcode 12.0 / iOS 14测试

代码语言:javascript
运行
复制
struct ContentView: View {
    @State var details = false
    @Namespace var animation
    
    var body: some View {
        ZStack {
            HStack {
                if !details {
                    Rectangle()
                        .matchedGeometryEffect(id: "id1", in: animation)
                        .frame(width: 100, height: 100)
                        .onTapGesture {
                            details.toggle()
                        }
                }
                Spacer()
            }.animation(.default, value: details)
            
            if details {
                AnotherView(details: $details, animation: animation)
            }
        }.animation(.default, value: details)
    }
}


struct AnotherView: View {
    @Binding var details: Bool
    var animation: Namespace.ID
    
    var body: some View {
        ZStack {
            Color.red
            
            Rectangle()
                .matchedGeometryEffect(id: "id1", in: animation)
                .frame(width: 300, height: 300)
                .onTapGesture {
                    details.toggle()
                }
        }
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64581837

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档