Edit:
I found a solution but I would really like to know why it behaves this way as I got the solution by simply trial and error.
The solution I found is to add .animation(.default, value: user.times)
modifier to the list in the child view. Why it works this way, I have no Idea.
I have this weird problem where when I pass a binding to a child view, changes inside this child view are not animated except for .onDelete
modifier.
Here is a simplified code that produces this problem:
Observable
(ViewModel) and model struct:
extension ContentView {
class ViewModel: ObservableObject {
@Published var users = [User]()
func createUser() {
users.append(User(times: []))
}
}
struct User: Equatable {
let name = UUID().uuidString
var times: [Date]
}
}
ContentView
: (Parent view)
struct ContentView: View {
@StateObject var vm = ViewModel()
var body: some View {
NavigationView {
List {
ForEach(vm.users.indices, id: \.self) { index in
NavigationLink {
UserView(user: $vm.users[index])
} label: {
Text(vm.users[index].name)
}
}
.onDelete { offsets in
vm.users.remove(atOffsets: offsets)
}
Button("Add") {
withAnimation {
vm.createUser()
}
}
}
.navigationTitle("Parent View")
}
}
}
UserView
(Child View):
struct UserView: View {
@Binding var user: ContentView.User
var body: some View {
List {
ForEach(user.times.indices, id: \.self) { index in
Text(user.times[index].description)
}
.onDelete { offsets in
user.times.remove(atOffsets: offsets)
}
Button {
withAnimation {
user.times.append(Date())
}
} label: {
Text("Add Time")
}
}
.navigationTitle("Child View")
}
}
Notice in below image that the parent view having almost exactly the same code except for binding is working and animating as intended, and notice the child view .onDelete
modifier is also animating as it intended but when adding to the list of child view, animation are not working.