SwiftUI 和 MVVM:当视图模型更改“数据源”(“@Publish items”)本身时如何动画“列表元素更改”

Vla*_*kov 5 mvvm swiftui

我对 SwfitUI 和 Combine 还比较陌生,所以也许我试图做一些非常错误的事情,但我只是不知道如何实现我想要用 SwiftUI 和 MVVM 实现的目标。这是场景:

  • ViewModel具有属性的类@Published var items = [String]()
  • 主视图(HomeView)显示ForEach其视图模型中的项目
  • HomeView 有一个@StateObject var viewModel: ViewModel
  • 使用HomeView ForEach来自itemsviewModel
  • ViewModel更改items(在我的例子中核心数据更改)
  • 立即反映HomeView ForEach变化

这一切都有效,但我想做的是为ForEach因变化而变化的元素设置动画viewModel.items

我能做的就是import SwiftUI进入ViewModel并使用withAnimation来包装 new 的设置items。但这违背了 ViewModel 的目的,因为它现在可以直接引用 UI 代码。

这是我的一些代码:

struct HomeView: View {
    @StateObject var viewModel: ViewModel

    var body: some View {
         ForEach(items) { item in
            Text(item)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
import SwiftUI // This should not be imported as it breaks MVVM patter

class ViewModel {
    @Published var items = [String]()

    func onItemsChanged(_ newItems: [String]) {
       withAnimation { // This works but will break MVVM patter
          items = newItems
       }
    }
}
Run Code Online (Sandbox Code Playgroud)

有什么想法可以实现这一点,让 MVVM 满意并与 SwiftUI 一起使用吗?

Asp*_*eri 5

将动画添加到保存视图项目的容器中,如下所示

var body: some View {
  VStack {                      // << container
     ForEach(items) { item in
        Text(item)
    }
  }
  .animation(.default)          // << animates changes in items
}
Run Code Online (Sandbox Code Playgroud)

有关完整示例,请参阅下一篇文章:/sf/answers/4262542371/、https : //stackoverflow.com/a/65776506/12299030、https : //stackoverflow.com/a/63364795/12299030