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:
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
Anyone has a hint how to adjust it to work properly? Thanks!
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)
}
}
}
}
}