【问题标题】:SwiftUI & MVVM: How to animate "list elements change" when view model changes the "data source" (`@Publish items`) itselfSwiftUI 和 MVVM:当视图模型更改“数据源”(`@Publish items`)本身时,如何为“列表元素更改”设置动画
【发布时间】:2021-05-31 11:32:10
【问题描述】:

我对 SwfitUI 和 Combine 还比较陌生,所以也许我正在尝试做一些非常不正确的事情,但我只是看不出如何使用 SwiftUI 和 MVVM 来实现我的目标。 这是场景:

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

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

我能做的是将import SwiftUI 放入ViewModel 并使用withAnimation 包装新items 的设置。但这超出了 ViewModel 的用途,因为它现在直接引用了 UI 代码。

这里有一些代码:

struct HomeView: View {
    @StateObject var viewModel: ViewModel

    var body: some View {
         ForEach(items) { item in
            Text(item)
        }
    }
}
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
       }
    }
}

是否有任何想法可以让 MVVM 满意并使用 SwiftUI?

【问题讨论】:

  • 您的 View 可以使用 Toggle 在您的 ViewModel 上观察一些 bool 属性,例如切换(“”,isOn:$viewModel.someBoolProperty)。这样您就可以将工作转移到 VIEW

标签: mvvm swiftui


【解决方案1】:

将动画添加到包含您的视图项的容器中,如下所示

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

完整示例请参见下一篇文章:https://stackoverflow.com/a/60893462/12299030https://stackoverflow.com/a/65776506/12299030https://stackoverflow.com/a/63364795/12299030

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-30
    • 2014-03-09
    • 1970-01-01
    • 2014-01-12
    • 2020-03-18
    • 1970-01-01
    • 2020-07-19
    • 1970-01-01
    相关资源
    最近更新 更多