【问题标题】:SwiftUI -pass image data f List -> Detail with scaling animation using matchedGeometryEffectSwiftUI - 传递图像数据 f 列表 -> 使用matchedGeometryEffect 缩放动画的细节
【发布时间】:2021-07-28 03:39:10
【问题描述】:

目标:从 List 传递图像数据 -> Detail 与 Apple Photos App 类似的动画缩放。

我做了什么:使用了匹配的几何效果,效果很好。

问题:我只能让它硬编码,因为我在同一个 ContentView() 上有 List() 和 Detail(),我不知道如何传递数据 List-> Detail

感谢任何输入!

import SwiftUI




struct Grid: View {
    
    let namespace: Namespace.ID
    
    var body: some View {
        
        List{
           Image("cover")
                .resizable()
                .frame(width: 50, height: 50)
                .cornerRadius(4)
                .padding()
                .matchedGeometryEffect(id: "animation", in: namespace)
            
            Image("cover2")
                 .resizable()
                 .frame(width: 50, height: 50)
                 .cornerRadius(4)
                 .padding()
                 .matchedGeometryEffect(id: "animation", in: namespace)
        }

   }
}

struct Detail: View {
    
    let namespace: Namespace.ID
    
    var body: some View {
        
            Image("cover")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .cornerRadius(10)
                .padding(40)
                .matchedGeometryEffect(id: "animation", in: namespace)
        
      
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color(#colorLiteral(red: 0.234857142, green: 0.043259345, blue: 0.04711621255, alpha: 1)))
    }
}

struct ContentView: View {
    
    @Namespace private var ns
    @State private var showDetails: Bool = false
    
    var body: some View {
        ZStack {
            Spacer()
            if showDetails {
                Detail(namespace: ns)
            }
            else {
                Grid(namespace: ns)
            }
        }
        .onTapGesture {
            withAnimation(.spring()) {
                showDetails.toggle()
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

【问题讨论】:

    标签: xcode swiftui swiftui-list


    【解决方案1】:

    您可以使用@EnvironmentObject 属性包装器在视图之间传递数据。 为此,您需要具有已发布属性的可观察对象类(例如 CoverData)。

    您还应该为要分组的视图使用 matchedGeometryEffect 的唯一 ID(例如图像名称)

    我对您的代码做了最小的更改,看看这是否是您要找的:

    import SwiftUI
    
    
    class CoverData: ObservableObject {
        @Published var images = ["cover", "cover2"]
        @Published var selected = ""
        @Published var showDetails: Bool = false
    }
    
    struct Grid: View {
        @EnvironmentObject var coverData: CoverData
        
        let namespace: Namespace.ID
        
        var body: some View {
            
            List {
                ForEach(coverData.images.indices) { index in
                    let image = coverData.images[index]
                    Image(image)
                        .resizable()
                        .frame(width: 50, height: 50)
                        .cornerRadius(4)
                        .padding()
                        .matchedGeometryEffect(id: image, in: namespace)
                        .onTapGesture {
                            coverData.selected = image
                            withAnimation(.spring()) {
                                coverData.showDetails.toggle()
                            }
                        }
                }
            }
       }
    }
    
    struct Detail: View {
        @EnvironmentObject var coverData: CoverData
    
        let namespace: Namespace.ID
        
        var body: some View {
            
                Image(coverData.selected)
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .cornerRadius(10)
                    .padding(40)
                    .matchedGeometryEffect(id: coverData.selected, in: namespace)
            
          
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .background(Color(#colorLiteral(red: 0.234857142, green: 0.043259345, blue: 0.04711621255, alpha: 1)))
        }
    }
    
    struct ContentView: View {
        
        @Namespace private var ns
        @StateObject private var coverData = CoverData()
        
        var body: some View {
            ZStack {
                Spacer()
                if coverData.showDetails {
                    Detail(namespace: ns)
                    .onTapGesture {
                        withAnimation(.spring()) {
                            coverData.showDetails.toggle()
                        }
                    }
                }
                else {
                    Grid(namespace: ns)
                }
            }
            .environmentObject(coverData)
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
    
    

    【讨论】:

    • 完美,谢谢@kamillo!你知道如何在解雇时制作动画吗?
    • @ManeManero,当 ZStack 上的动画视图具有相同的 (0) 索引时,它们似乎存在一些问题,这可以通过为详细视图设置 zIndex 来解决,例如.zIndex(1.0)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-11
    • 1970-01-01
    • 1970-01-01
    • 2014-12-05
    • 1970-01-01
    • 2021-11-07
    • 1970-01-01
    相关资源
    最近更新 更多