Animation 在ScrollView中使用matchedGeometryEffect动画时出现问题

Animation 在ScrollView中使用matchedGeometryEffect动画时出现问题,animation,swiftui,swiftui-scrollview,Animation,Swiftui,Swiftui Scrollview,使用matchedGeometryEffect在LazyVGrid和HStack之间设置视图动画(在本例中为按钮),效果非常好: 注意动画视图如何在“完成”按钮上方移动 但是,当视图包含在滚动视图中时,动画视图现在移动到中间视图的后面: 我已经尝试将ScrollViews的zIndex设置为>0(或更多),但这似乎没有改变任何事情 有没有关于如何解决这个问题的想法 人 struct Person: Identifiable, Equatable { var id: String {

使用
matchedGeometryEffect
LazyVGrid
HStack
之间设置
视图
动画(在本例中为
按钮
),效果非常好:

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

但是,当视图包含在
滚动视图中时,动画视图现在移动到中间视图的后面:

我已经尝试将
ScrollView
s的
zIndex
设置为>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)
    }
}
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)
    }
}
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)!)
    }
}
SelectedPeopleView

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)
    }
}
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)
    }
}
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)!)
    }
}
人物视图

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)
    }
}
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)
    }
}
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中的一个bug,因为即使您将
颜色。清除
任何高度以代替您的
doneButton
(或者甚至
。为底部
ScrollView
)填充一些高度,效果将是相同的

从视图层次结构可以看出,两个
滚动视图之间没有任何内容,图像的渲染在一个背景视图中执行


谢谢-我也找到了。在Apple(FB8458770)上引发错误