在 ScrollView 中使用matchedGeometryEffect 动画的问题

Posted

技术标签:

【中文标题】在 ScrollView 中使用matchedGeometryEffect 动画的问题【英文标题】:Issue using matchedGeometryEffect animation in ScrollView 【发布时间】:2020-08-18 20:18:06 【问题描述】:

使用matchedGeometryEffectLazyVGridHStack 之间使用另一个视图(在本例中为Button)对Views 进行动画处理,效果很好:

注意动画视图是如何移动到完成按钮之上的。

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

我尝试将ScrollViews 的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)
    

内容视图

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)
    

人物视图

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)!)
    

【问题讨论】:

【参考方案1】:

这看起来像 SwiftUI 中的一个错误,因为即使您将任何高度的 Color.clear 代替而不是您的 doneButton(或者甚至是底部 ScrollView 的某个高度的 .padding),效果也会一样。

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

【讨论】:

谢谢 - 我也找到了。引发了 Apple 的错误 (FB8458770) ios 15.1 和 swiftUI 3 上遇到同样的问题 :( 有什么解决办法吗?

以上是关于在 ScrollView 中使用matchedGeometryEffect 动画的问题的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Xcode 6.3 中使用 AutoLayout 创建 ScrollView

如何使用 SnapKit 在 ScrollView 中居中按钮数组

在 ScrollView 中使用 GeometryReader 的 SwiftUI 布局

无法在 SlidingUpPanelLayout Xamarin Android 中使用 ScrollView 布局

如何在 SwiftUI 中使用 ScrollView(不滚动)[重复]

在 ScrollView 中使用matchedGeometryEffect 动画的问题