首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >ForEach匹配几何效应

ForEach匹配几何效应
EN

Stack Overflow用户
提问于 2021-12-26 13:59:32
回答 1查看 534关注 0票数 1

我有一个非常简单的场景,一个带有缩略图( ForEach of缩略图,ElementView)的列表,如果您单击其中一个,它将作为一个全屏详细信息视图(DetailView)打开。我想为此使用matchedGeometryEffect,以实现英雄动画。它几乎运行良好,但动画仍然不完美,看起来如果两个视图是分开处理的。

CollectionView.swift

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct CollectionView: View {
    var data = [
        "Test card 1",
        "Test card 2",
        "Test card 3",
        "Test card 4",
        "Test card 5"
    ]

    @State var selectedElement: String?

    @Namespace var namespace

    var body: some View {
        VStack {
            if selectedElement == nil {
                ScrollView {
                    LazyVGrid(columns: [GridItem(), GridItem()]){
                        ForEach(data.indices, id: \.self) { idx in
                            ElementView(text: data[idx])
                                .matchedGeometryEffect(id: idx, in: namespace, properties: .position)
                                .transition(.scale)
                                .onTapGesture {
                                    withAnimation {
                                        selectedElement = data[idx]
                                    }
                            }
                        }
                    }
                }
            } else {
                ForEach(data.indices, id: \.self) { idx in
                    if data[idx] == selectedElement {
                        DetailView(
                            text: selectedElement!,
                            backDidTap: {
                                withAnimation { selectedElement = nil }
                            }
                        )
                            .matchedGeometryEffect(id: idx, in: namespace, properties: .position)
                            .transition(.scale)
                    }
                }
            }
        }
    }
}

ElementView.swift

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct ElementView: View {
    let text: String
    var body: some View {
        LazyVStack(spacing: .zero) {
            Color.black
                .frame(width: UIScreen.main.bounds.width / 2, height: UIScreen.main.bounds.width / 2)
            Text(text)
                .padding(.top, 8)
                .frame(width: UIScreen.main.bounds.width / 2)
        }
    }
}

DetailView.swift

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct DetailView: View {
    let text: String
    let backDidTap: () -> Void
    var body: some View {
       VStack(alignment: .leading, spacing: .zero) {
           Color.black
               .edgesIgnoringSafeArea(.all)
               .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height / 2)
               .onTapGesture {
                   backDidTap()
               }
           Text(text)
               .padding(.top, 8)
               .padding(.leading, 8)
           Spacer()
       }
    }
}

在模拟器上启用“慢动画”的结果:https://i.imgur.com/hW4qR6t.mp4

我认为这种转变有些不对劲,但我想不出是什么。我已经尝试过this了,因为问题非常相似,但是这种自定义转换对我不起作用。

EN

回答 1

Stack Overflow用户

发布于 2022-06-14 06:13:21

也许你已经找到了答案,但以下是我的解决方案:

问题是,在根视图中删除原始视图的条件是if。,因此swiftUI现在不再是视图动画的原始状态。这是我的解决方案:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
struct CollectionView: View {
    var data = [
        "Test card 1",
        "Test card 2",
        "Test card 3",
        "Test card 4",
        "Test card 5"
    ]

    @State var selectedElement: String?

    @Namespace var namespace

    var body: some View {
        ZStack {
                ScrollView {
                    LazyVGrid(columns: [GridItem(), GridItem()]){
                        ForEach(data.indices, id: \.self) { idx in
                            ElementView(text: data[idx])
                                .matchedGeometryEffect(id: data[idx], in: namespace, properties: .position)
                                //.transition(.scale)
                                .onTapGesture {
                                    withAnimation {
                                        selectedElement = data[idx]
                                    }
                            }
                        }
                    }
                }
                .zIndex(1)
            
            if let selected = selectedElement {
                DetailView(text: selected, backDidTap: {
                    withAnimation { selectedElement = nil }
                })
                    .matchedGeometryEffect(id: selected, in: namespace)
                    //.transition(.scale)
                    .zIndex(2)
            }
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70490144

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文