在ScrollView中使用matchedGeometryEffect动画的问题

问题描述

使用View使LazyVGridHStack间的Button动画化,并且在它们之间有另一个视图(在这种情况下为matchedGeometryEffect),效果很好:

enter image description here

请注意动画视图如何在上方完成按钮上移动。

但是,当视图包含在ScrollView中时,动画视图现在移到中间视图之后 >

enter image description here

我尝试将zIndex中的ScrollView设置为> 0(或更多),但这似乎没有任何改变。

关于如何解决此问题的任何想法?

人员

struct Person: Identifiable,Equatable {
    var id: String { name }
    let name: String
    var image: Image { Image(name) }
    
    static var all: [Person] {
        ["Joe","Kamala","Donald","Mike"].map(Person.init)
    }
}

ContentView

struct ContentView: View {

    @State var people: [Person]
    @State private var selectedPeople: [Person] = []
    @Namespace var namespace

    var body: some View {
        vstack(alignment: .leading,spacing: 0) {
            ScrollView(.horizontal) {
                SelectedPeopleView(people: $selectedPeople,namespace: namespace) { person in
                    withAnimation(.eaSEOut(duration: 1)) {
                        selectPerson(person)
                    }
                }
                .background(Color.orange)
            }
            doneButton()
            ScrollView(.vertical) {
                PeopleView(people: people,namespace: namespace) { person in
                    withAnimation(.eaSEOut(duration: 1)) {
                        deselectPerson(person)
                    }
                }                
            }
            Spacer()
        }
        .padding()
    }

    func selectPerson(_ person: Person) {
        _ = selectedPeople.firstIndex(of: person).map { selectedPeople.remove(at: $0)}
        people.append(person)
    }

    func deselectPerson(_ person: Person) {
        _ = people.firstIndex(of: person).map { people.remove(at: $0)}
        selectedPeople.append(person)
    }

    func doneButton() -> some View {
        Button("Done") {
        }
        .font(.title2)
        .accentColor(.white)
        .frame(maxWidth: .infinity)
        .padding()
        .background(Color.gray)
    }
}

SelectedPeopleView

struct SelectedPeopleView: View {

    @Binding var people: [Person]
    let namespace: Namespace.ID
    let didSelect: (Person) -> Void

    var body: some View {
        HStack {
            ForEach(people) { person in
                Button(action: { didSelect(person) } ) {
                    Text(person.name)
                        .padding(10)
                        .background(Color.yellow.cornerRadius(6))
                        .foregroundColor(.black)
                        .matchedGeometryEffect(id: person.id,in: namespace)
                }
            }
        }
        .frame(height: 80)
    }
}

PeopleView

struct PeopleView: View {

    let people: [Person]
    let namespace: Namespace.ID
    let didSelect: (Person) -> Void

    let columns: [GridItem] = Array(repeating: .init(.flexible(minimum: .leastnormalMagnitude,maximum: .greatestFiniteMagnitude)),count: 2)

    var body: some View {
        LazyVGrid(columns: columns) {
            ForEach(people) { person in
                Button(action: { didSelect(person) }) {
                    person.image
                        .resizable()
                        .scaledToFill()
                        .layoutPriority(-1)
                        .clipped()
                        .aspectRatio(1,contentMode: .fit)
                        .cornerRadius(6)
                }
                .zIndex(zIndex(for: person))
                .matchedGeometryEffect(id: person.id,in: namespace)
            }
        }
    }

    func zIndex(for person: Person) -> Double {
        Double(people.firstIndex(of: person)!)
    }
}

解决方法

这看起来像SwiftUI中的错误,因为即使您将Color.clear的高度替换为doneButton(甚至.padding的底部高度{ {1}})的效果相同。

demo

从视图层次结构中可以看出,两个ScrollView之间没有任何内容,并且图像渲染是在一个背景视图中完成的。

demo2

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...