2

I have a LazyVGrid that is defined like this:

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

I have a button, that starts an animation effect:

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

The animation should add the new Red squares into the grid one by one with 1 second intervals using a slide effect, but there are 2 issues:

  1. even though I set a specific transition for the Red color view, the transition is ignored and the squares are added with a fade in effect

image1

  1. each time the first square in the row, is added in a new row on the grid, it appears from the middle of the row, and starts to slide vertically, the next squares in same row fade in

image2

It appears I'm setting the transition and animation in the wrong place, because even if remove the .transition from the Red view, it still animates it the same way. Can't understand what controls it

image3

Anyone has a hint how to adjust it to work properly? Thanks!

skalber
  • 467
  • 4
  • 14
  • Any news on this. I have same issue :/ It is weird because only insertion animation is not working and it is not working only when there is no elements at all. If elements are in Grid then animation works correctly. – Rafał Wójcik Jul 11 '22 at 11:35
  • couldn't find a solution or the reason it happens. I decided to wrap it in a ScrollView like suggested in the answer and just accept the fade animation which occurs – skalber Jul 11 '22 at 12:58

1 Answers1

3

I can reproduce your issue, and I don't know why it happens.
But I found a possible solution. If you wrap the LazyVGrid in s ScrollView it works:

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

ChrisR
  • 9,523
  • 1
  • 8
  • 26