I'm trying to add animations to a list view when using some controls and an undo + redo button. I've added withAnimation closures to my buttons, but when I double tap a button the list view falls out of sync with the backing state and doesn't refresh. I find I'll often undo multiple steps at a time, so this is a pattern I expect users to experience frequently.
My understanding of why this happens is that during animations state changes don't trigger a new render.
I've created an MVP of the issue:
import SwiftUI
struct MyListView: View {
@State var data: [UUID] = []
var body: some View {
VStack{
HStack{
Button("Add", action: {
withAnimation(Animation.linear(duration: 2)){ // Offending animation
data.append(UUID())
}
})
Spacer()
Button("Clear", action: {
withAnimation{
data.removeAll()
}
})
Spacer()
Text("Count: \(data.count)")
}
List{
ForEach(data, id: \.self) { v in
Text("\(v)")
}
.onMove(perform: { indices, newOffset in
data.move(fromOffsets: indices, toOffset: newOffset)
})
.onDelete(perform: { indexSet in
data.remove(atOffsets: indexSet)
})
}
}
.padding()
}
}
struct MyListView_Previews: PreviewProvider {
static var previews: some View {
MyListView()
.environment(\.editMode, .constant(.active))
}
}
If you run this code in the simulator you can reproduce the issue by rapidly pressing the Add button.
I've been unable to find anything on Google that really provided insight to the right way to solve this issue. I've explored if Transactions could fix the issue but that doesn't seem like the solution, and I haven't found anything on how to interrupt the animation to start a new one without re-rendering the view.
I'm starting to think the answer is to just not animate undo/redo and appending, or relying on some other form of feedback to the user.
Any help would be appreciated, thanks.