如何将数据从父模型类传递到 SwiftUI 中的子视图
Posted
技术标签:
【中文标题】如何将数据从父模型类传递到 SwiftUI 中的子视图【英文标题】:How to pass data from a parent model class to a subview in SwiftUI 【发布时间】:2021-06-17 01:34:17 【问题描述】:我在 ContentView 类中有我的主视图,我在 ContentViewModel 类中进行网络调用,并使用响应更新类调用 User。
我的 ContentView 有几个子视图,例如 HeaderView。当我从 API 响应更新 User 类属性时,我也想更新 HeaderView 中定义的 UI 元素。如何将数据从 ContentViewModel 类传递到我的子视图(HeaderView)?
我可以通过设置 ContentViewModel 类 ObservableObject 来更新非常简单的 ContentView 元素
class ContentViewModel: ObservableObject
并发布了用户对象
@Published var user = User()
并在我在同一个 ContentViewModel 中收到 API 响应后更新用户的属性
self.user.name = name
我的 ContentView 与其模型类的关系如下所示
@StateObject private var contentViewModel = ContentViewModel()
UI 更新如下
Text("My name \(contentViewModel.user.name)")
这就是 ContentView 的工作场景。但我需要将值传递给 HeaderView()。 我的用户类如下所示
import Foundation
class User
var name = ""
// more attributes
【问题讨论】:
你能显示HeaderView
的代码吗?也许只使用Binding
【参考方案1】:
这是我经常使用的模式:(注意没有私有变量)
struct ContentView: View
@StateObject var contentViewModel = ContentViewModel()
...
var body: some View
...
HeaderView(contentViewModel: contentViewModel)
struct HeaderView: View
@ObservedObject var contentViewModel: ContentViewModel
var body: some View
...
Text("My name \(contentViewModel.user.name)")
struct User
var name = ""
// more attributes
您可以使用相同的想法与“.environment(...)”模式将 ContentViewModel 传递给所有子视图。
编辑:正如@Asperi 建议的那样,用户应该成为一个结构。
【讨论】:
不应该HeaderView
的StateObject
是ObservedObject
?
你应该在HeaderView中使用@ObservedObject,见***.com/questions/62544115/…
@workingdog 答案和@Asperi 答案的组合有效。对于我们的主视图在几个子视图中构建的场景,我们没有直接的 UI 重绘属性,我们需要 @Asperi 提供的建议。如果您可以用他的建议更新您的答案(也给予他的信任:)),我可以接受这是正确的答案。 (因为我不能接受一个问题的两个答案:D)。此外,您可以提供.environment(...)
选项作为另一种丰富您的答案的方法。非常感谢。
当您将根“视图模型”传递给“子视图”(HeaderView) 时,子视图不能再用作组件 - 这在很大程度上取决于特定的视图模型。将“子视图状态”传递给子视图将是一种改进。子视图的“动作”(又名意图,又名事件)可以用子视图中的函数实例(回调)来建模。父视图设置子状态和操作功能(并处理从子视图发送的用户操作和其他操作,它只是发送到视图模型)。【参考方案2】:
当我从 API 响应更新用户类属性时,我想更新 UI
无论您如何将模型传递给子视图,它都不会更新,因为您的 User
是一个 类,因此更改其属性不会激活发布(因为已发布的包装器包含引用未更改的用户),因此视图未更新。
相反,您应该将 User
设为结构
struct User
var name = ""
// more attributes
或将其设为ObservableObject
,同时发布所有需要的属性,并通过引用传递给以常规方式观察它的子视图。
【讨论】:
以上是关于如何将数据从父模型类传递到 SwiftUI 中的子视图的主要内容,如果未能解决你的问题,请参考以下文章