ios 如何在SwiftUI中将数据从父模型类传递到子视图

bq8i3lrv  于 2023-01-03  发布在  iOS
关注(0)|答案(2)|浏览(144)

我在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
}
8i9zcol2

8i9zcol21#

这是我经常使用的模式:(注意无私有变量)

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的建议,用户应该成为一个结构体。

thtygnil

thtygnil2#

当我从API响应更新User类属性时,我想更新UI
不管你如何将你的模型传递给子视图,它都不会更新,因为你的User是-a class,所以改变它的属性不会激活发布(因为发布的 Package 器持有一个对User的引用,这个引用没有改变),所以视图不会更新。
相反,您应该将User设置为结构体

struct User {
    var name = ""
// more attributes
}

或者使其也具有发布的所有所需属性并且通过引用传递给以常规方式观察它的子视图。

相关问题