SwiftUI中的LazyVGrid过渡动画效果与预期不符。

3

我有一个懒加载网格视图,定义如下:

let column = Array(repeating: GridItem(.flexible(minimum: 120, maximum: .infinity)), count: 3)
        
LazyVGrid(columns: column, alignment: .leading, spacing: 5) {
    ForEach(data, id: \.self.uniqueStableId) { _ in
        Color.red
             .transition(.move(edge: .trailing))
             .frame(height: 150)
    }
}

我有一个按钮,它可以启动一个动画效果:

func handleButtonTap() {
    for index in 0..<9 {
        DispatchQueue.main.asyncAfter(deadline: .now() + Double(1 * index)) {
            withAnimation(.easeInOut(duration: 1)) {
                let newItem = Item()
                self.data.append(newItem)                                                                                     
            }
        }
    }
}

动画应该使用滑动效果,每隔1秒将新的红色方块逐个添加到网格中,但是有两个问题:
  1. 即使我为红色视图设置了特定的过渡效果,过渡仍被忽略,方块以淡入效果添加

image1

  1. 每次在网格上的新行中添加第一个方块时,它会从该行中间出现,并开始垂直滑动,同一行中的下一个方块则以淡入方式出现

image2

看起来我把过渡和动画设置在了错误的位置,因为即使我从红色视图中删除.transition,它仍然以相同的方式进行动画。无法理解是什么控制了它

image3

有人有调整它正常工作的提示吗? 谢谢!


有关此事有任何消息吗?我也遇到了同样的问题 :/ 这很奇怪,因为只有插入动画不起作用,而且仅在没有任何元素时才不起作用。如果网格中有元素,则动画可以正常工作。 - Rafał Wójcik
找不到解决办法或发生原因。我决定像答案中建议的那样将其包装在ScrollView中,并接受淡入淡出动画。 - skalber
1个回答

4

我可以复现你的问题,但是不知道为什么会发生这种情况。
但是我找到了一个可能的解决方案。如果你将 LazyVGrid 包裹在 ScrollView 中,它就可以正常工作:

struct Item: Identifiable {
    let id = UUID()
}

struct ContentView: View {
    
    @State private var data: [Item] = []
    let column = Array(repeating: GridItem(.flexible()), count: 3)
    
    var body: some View {
        VStack {
            Button("Add") { handleButtonTap() }
            
            ScrollView {
            LazyVGrid(columns: column, alignment: .leading, spacing: 5) {
                ForEach(data) { _ in
                    Color.red
                        .frame(height: 150)
                        .transition(.move(edge: .trailing))
                }
            }
            Spacer()
            }
        }
    }
    
    func handleButtonTap() {
        for index in 0..<9 {
            DispatchQueue.main.asyncAfter(deadline: .now() + Double(1 * index)) {
                withAnimation(.easeInOut(duration: 1)) {
                    let newItem = Item()
                    self.data.append(newItem)
                }
            }
        }
    }
    
}

enter image description here


谢谢!它解决了行中第一个单元格的问题,但我不确定为什么对于我的情况转换仍然被忽略并且出现了淡入效果。 - skalber
你还能看到淡入效果吗?我的代码和你的有什么不同? - ChrisR
只有一个区别,我正在尝试在Mac OS应用程序上运行它。 - skalber
啊,那是一个相关的信息;)但我的代码在 macOS 上也能正常工作。没有淡入效果,只是从.trailing移动进来。 - ChrisR
谢谢,我会继续调查。 - skalber
谢谢 - 现在是2023年11月,这在Xcode 15中仍然是一个问题。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接