SwiftUI:从 ViewModel 更改视图 @State 属性

Posted

技术标签:

【中文标题】SwiftUI:从 ViewModel 更改视图 @State 属性【英文标题】:SwiftUI: Change view @State property from ViewModel 【发布时间】:2021-11-24 11:13:57 【问题描述】:

我的视图中有这样的日期选择器:

struct BookTimeView: View 
    @ObservedObject var viewModel: BookTimeViewModel

    @State var startTime = Date.now
    
 
     var body: some View 
         DatePicker(“pick time”, selection: $startTime, displayedComponents: .hourAndMinute)
     

初始 startTime 取决于后端的数据。

所以在视图模型中我有从后端加载数据的 API 调用。

在成功回调中我想更改 startTime。

问题:如何从 ViewModel 更改 startTime?

P.S.:是否可以直接将 DatePicker 与 ViewModel 绑定?

我试图将@State var startTime = Date.now 放在视图模型中。 但它不起作用,我在 Xcode 中看到警告:

Accessing State's value outside of being installed on a View. This will result in a constant Binding of the initial value and will not update.

【问题讨论】:

为什么不直接将DatePicker绑定到viewModel @Asperi 当我在 ViewModel 中放置 State 属性时,我看到下一个警告:在安装到 View 之外访问 State 的值。这将导致初始值的常量绑定,并且不会更新。 让它使用你的api更新的和@Published 我要绑定到已发布的属性,例如***.com/a/60058909/12299030。 @Asperi 哇。那就是我要找的。谢谢大佬!! 【参考方案1】:

您可以直接绑定到@Published 属性,只需:

$viewModel.startTime

它将属于Binding<Date> 类型,即使我们将其声明为BookTimeViewModel 上的@Published 属性。

示例代码:

class BookTimeViewModel: ObservableObject 
    @Published var startTime: Date = .now

struct BookTimeView: View 
    @ObservedObject var viewModel: BookTimeViewModel

    var body: some View 
        DatePicker("pick time", selection: $viewModel.startTime, displayedComponents: .hourAndMinute)
    

类似于我的回答here。

【讨论】:

如何将 Date 对象分配给 startTime: Binding ? @Jim 分配,例如,你可以只做viewModel.startTime = Date.now。上面的代码是为你的DatePicker创建一个Binding 当我尝试将 Date.now 分配给 startTime: Binding 我收到错误消息,指出无法将 Date 分配给 Binding @Jim 您希望将BookTimeViewModel 中的startTime 声明为@Published var startTime = Date.now。然后你可以像上面提到的那样做viewModel.startTime = Date.now,并为它删除@State变量。请记住在设置新值时删除$ 问题在于 DatePicker 仅适用于 Binding。所以我不能只使用Publisher。它应该是 State 或 Binding

以上是关于SwiftUI:从 ViewModel 更改视图 @State 属性的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 从 ViewModel 预填充 TextField

基于 VIewModel 状态更新 SwiftUI 视图?

如何在 SwiftUI 中通过 ViewModel 传播模型更改?

SwiftUI:从嵌套视图调用方法

SwiftUI 将@Published viewmodel 对象值传递给@Binding

SwiftUI ChildView 未在状态更改时重新计算