使用新的@StateObject将模型传递给多个视图?

时间:2020-06-27 16:34:02

标签: swiftui

如果要在多个视图之间传递模型,可以多次使用@StateObject(请参见下面的示例),以便每个视图可以修改对象吗?我赞赏使用@EnvironmentObject可以更好地完成此操作,但只是想了解这种新属性包装程序在这种情况下如何工作。

// MARK: - MODEL
class Model: ObservableObject {
   @Published var temperature = 27.5
}

// MARK: - APP.SWIFT
@main
struct SwiftUI_DataFlow_005App: App {
    @ObservedObject var model = Model()
    var body: some Scene {
        WindowGroup {
            ContentView(model: model)
        }
    }
}

// MARK: - CONTENT VIEW
struct ContentView: View {
    @StateObject var model: Model
    var body: some View {
        VStack {
            Text("\(model.temperature)")
            AnotherView(model: model)
        }
    }
}

// MARK: - ANOTHER VIEW
struct AnotherView: View {
    @StateObject var model: Model
    var body: some View {
        Text("\(model.temperature)")
    }
}

2 个答案:

答案 0 :(得分:2)

@StateObject是真理的源头,因此必须在一个地方创建,因此(示意性地提供了屏幕截图,但没有修改代码)

in App >
  @StateObject private var model = Model()

  ...

  ContentView().environmentObject(model)

  ...

in ContentView >

  @EnvironmentObject var model: Model

  ...

in AnotherView >

  @EnvironmentObject var model: Model

答案 1 :(得分:1)

基于已接受的答案的小扩展,以便将来的读者获得更多的见识。

1-@ObservedObject

APPLE: Managing Model Data in Your App

从Apple文档看来,一种解决方案是在所有三个视图上使用@ObservedObject。

// MARK: - CONTENT VIEW
struct ContentView: View {
    @ObservedObject var model: Model
    var body: some View {
        VStack {
            Text("\(model.temperature)")
            AnotherView(model: model)
        }
    }
}

// MARK: - ANOTHER VIEW
struct AnotherView: View {
    @ObservedObject var model: Model
    var body: some View {
        Text("\(model.temperature)")
    }
}

2-@EnvironmentObject

另一种@asperi解决方案,到目前为止,最简单的方法是在app.swift中将模型创建为@StateObject,然后将对象注入到环境中。然后,这意味着您不必通过层次结构传递模型,而需要使用@EnviromentObject对其进行访问。

// MARK: - APP.SWIFT
@main
struct SwiftUI_DataFlow_005App: App {
    @StateObject var model = Model()
    var body: some Scene {
        WindowGroup {
            ContentView().environmentObject(model)
        }
    }
}

// MARK: - CONTENT VIEW
struct ContentView: View {
    @EnvironmentObject var model: Model
    var body: some View {
        VStack {
            Text("\(model.temperature)")
            AnotherView()
        }
    }
}

// MARK: - ANOTHER VIEW
struct AnotherView: View {
    @EnvironmentObject var model: Model
    var body: some View {
        Text("\(model.temperature)")
    }
}