代码之家  ›  专栏  ›  技术社区  ›  fs_tigre

将matchedGeometryEffect应用于列表视图内的视图时,列表视图中的项目会受到影响-SwiftUI

  •  0
  • fs_tigre  · 技术社区  · 1 年前

    我正在尝试使用动画从主视图过渡到第二个视图 .matchedGeometryEffect 但出于某种原因,如果我应用 .matchedGeometryEffect 直接到 Text(item.name) 只有一个项目是可见的,其余的都被隐藏了。如果我申请 .matchedGeometryEffect 直接到 List 所有项目都会显示,当它移动到第二个视图时,我会得到动画,但这不是我想要的效果,当我应用时,我得到了更好的效果 .matchedGeometryEffect 文本(项目名称)

    知道为什么我申请时列表中的大多数项目都消失了吗 .matchedGeometryEffect 文本(项目名称) ?

    内容视图

    struct ContentView: View {
        @State var showEditView = false
        @State var selectedItem:Item?
        @Namespace var editViewAnaimation
        
        let items = [Item(name: "Fork", symbolName: "fork.knife"),
                    Item(name: "Hammer", symbolName: "hammer.fill"),
                    Item(name: "Lightbulb", symbolName: "lightbulb.fill")]
        
        var body: some View {
            VStack {
                if showEditView{
                    Button(action: {
                        withAnimation{
                            showEditView.toggle()
                        }
                    }, label: {
                        Image(systemName: "xmark.square.fill")
                            .foregroundColor(Color.red)
                    })
                    EditView( editViewAnaimation: editViewAnaimation, selectedItem: selectedItem!)
                }else{
                    List(items, id:\.self){ item in
                        HStack{
                            Image(systemName: item.symbolName)
                                .foregroundColor(Color.red)
                            Text(item.name)
                                .foregroundColor(Color.blue)
                               /// some items disappear when applied here, why?
                               //.matchedGeometryEffect(id: "name", in: editViewAnaimation)
                        }
                        .onTapGesture {
                            selectedItem = item
                            withAnimation{
                                showEditView.toggle()
                            }
                        }
                    }
                    /// all items show when applied here but not the effect I want
                    .matchedGeometryEffect(id: "name", in: editViewAnaimation)
                }
            }
        }
    }
    

    编辑视图

    struct EditView: View {
        var editViewAnaimation: Namespace.ID
        let selectedItem:Item
        @State var nameInput = ""
        
        var body: some View {
            ScrollView{
                TextField("name", text: $nameInput)
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                    .matchedGeometryEffect(id: "name", in: editViewAnaimation)
            }
            .padding()
            .onAppear{
                nameInput = selectedItem.name
            }
        }
    }
    
    1 回复  |  直到 1 年前
        1
  •  1
  •   Sweeper    1 年前

    您对所有 Text s.这意味着 每一个 文本 的框架将匹配。“Fork”文本将与“Hammer”匹配,也将与“Lightbulb”匹配。所有的文本都会叠加在一起,所以你只能看到一条文本。

    你应该把 matchedGeometryEffect 上的修饰符 文本 s、 并给他们每个人一个合适的id。例如,您可以使用项目的名称作为id:

    Text(item.name)
        .foregroundColor(Color.blue)
        .matchedGeometryEffect(id: item.name, in: editViewAnaimation)
    
    TextField("name", text: $nameInput)
        .textFieldStyle(RoundedBorderTextFieldStyle())
        .matchedGeometryEffect(id: selectedItem.name, in: editViewAnaimation)
    

    你只想要“叉子” 文本 以匹配“叉子” TextField ,“锤子” 文本 以匹配“锤子” 文本字段