SwiftUI之如何使用@EnvironmentObject在视图之间共享数据
Posted Forever_wj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SwiftUI之如何使用@EnvironmentObject在视图之间共享数据相关的知识,希望对你有一定的参考价值。
- 对于应该与应用程序中的许多视图共享的数据,SwiftUI 为我们提供了 @EnvironmentObject 属性包装器,这让我们可以在任何需要的地方共享模型数据,同时还确保我们的视图在数据更改时自动保持更新。
- 可以把 @EnvironmentObject 看作在许多视图上使用,是一种比 @ObservedObject 更智能、更简单的方式。与其在视图 A 中创建一些数据,然后将其传递给视图 B,然后是视图 C,然后是视图 D 才最终使用它,可以在视图 A 中创建它并将其放入环境中,以便视图 B、C 和 D 将自动访问它。
- 就像 @ObservedObject 一样,永远不会为 @EnvironmentObject 属性赋值。相反,它应该从其他地方传入,最终您可能想要使用 @StateObject 在某处创建它。但是,与 @ObservedObject 不同的是,我们不会手动将对象传递到其它视图中。相反,使用将数据发送到一个名为 environmentObject() 的修饰符,这使得该对象在 SwiftUI 的环境中可用于该视图以及其中的任何其它对象(需要注意:环境对象必须由父视图提供,如果 SwiftUI 找不到正确类型的环境对象,程序就会崩溃,这也适用于预览,所以要小心)、
- 为了演示环境对象,我们将定义三件事:
-
- 一个 GameSettings 类,其中包含一个名为 score 的已发布属性;
-
- 期望在环境中接收 GameSettings 对象并显示其 score 属性的 ScoreView 视图;
-
- 一个创建 GameSettings 对象的 ContentView 视图,有一个按钮可以将 1 添加到它的 score 属性,还有一个 NavigationLink 来显示详细信息视图。
- 如下所示:
// Our observable object class
class GameSettings: ObservableObject
@Published var score = 0
// A view that expects to find a GameSettings object
// in the environment, and shows its score.
struct ScoreView: View
@EnvironmentObject var settings: GameSettings
var body: some View
Text("Score: \\(settings.score)")
// A view that creates the GameSettings object,
// and places it into the environment for the
// navigation view.
struct ContentView: View
@StateObject var settings = GameSettings()
var body: some View
NavigationView
VStack
// A button that writes to the environment settings
Button("Increase Score")
settings.score += 1
NavigationLink(destination: ScoreView())
Text("Show Detail View")
.frame(height: 200)
.environmentObject(settings)
- 分析该代码中几个重要部分:
-
- 就像 @StateObject 和 @ObservedObject 一样,所有与 @EnvironmentObject 一起使用的类都必须符合ObservableObject 协议;
-
- 将 GameSettings 放入导航视图的环境中,这意味着导航视图中的所有视图都可以根据需要读取该对象,以及导航视图显示的任何视图;
-
- 当使用 @EnvironmentObject 属性包装器时,声明希望接收的事物类型,但并没有创建它,毕竟我们希望从环境中接收它;
-
- 因为我们的细节视图显示在导航视图中,所以它可以访问相同的环境,这意味着它可以读取我们创建的 GameSettings 对象;
-
- 不需要将环境中的 GameSettings 实例与 ScoreView 中的 settings 属性显式关联,SwiftUI 会自动确定它在环境中具有一个 GameSettings 实例,因此它就是它使用的实例。
- 既然我们的视图依赖于存在的环境对象,那么更新预览代码以提供一些要使用的示例设置也很重要。 例如,使用 ScoreView().environmentObject(GameSettings()) 之类的东西进行预览应该这样做。
- 如果需要向环境添加多个对象,应该添加多个 environmentObject() 修饰符,只需一个接一个地调用它们。
以上是关于SwiftUI之如何使用@EnvironmentObject在视图之间共享数据的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI之深入解析如何使用组合矩形GeometryReader创建条形(柱状)图