[SwiftUI 100 天] 用 @EnvironmentObject 在 tab 间共享数据
2020/6/23 23:26:53
本文主要是介绍[SwiftUI 100 天] 用 @EnvironmentObject 在 tab 间共享数据,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
译自 www.hackingwithswift.com/books/ios-s…
更多内容,欢迎关注公众号 「Swift花园」
喜欢文章?不如来个 🔺💛➕三连?关注专栏,关注我 🚀🚀🚀
用 @EnvironmentObject 在 tab 间共享数据
SwiftUI 的 environment 可以让我们以一种相当优雅的方式共享数据:任何视图都可以把数据发送到环境中,然后任何子视图都可以从环境中读出这些数据。更棒的是,如果一个视图改变对象,所有其他视图都会自动更新 —— 这是一种极为聪明的在大型应用中共享数据的方式。
我们的应用中有 TabView
,它包含了三个 ProspectView
实例,我们需要它们是基于相同的共享数据运作的三个不同的视图。这是 SwiftUI 环境工作机制的绝佳示例:我们可以定义一个类来存储 prospect,然后用一组 prospect 注入环境,以便所有视图可以按需读取。
新建一个 Swift 文件,取名 Prospect.swift,把 Foundation 导入替换为 SwiftUI,然后添加下面的代码:
class Prospect: Identifiable, Codable { let id = UUID() var name = "Anonymous" var emailAddress = "" var isContacted = false } 复制代码
是的,这里采用类而不是结构体是有意为之,因为这样能让我们直接修改类的实例,让它在所有视图之间同时更新。记住,SwiftUI 是自动处理变化的传播过程。
说到在多个视图间共享数据,SwiftUI 的 environment 有一大好处是它采用的是相同的 ObservableObject
协议,我们之前已经用它配合 @ObservedObject
属性包装器。这意味着,只要我们给属性标记 @Published
属性包装器 —— SwiftUI 自动为我们完成大部分工作。
把这个类添加到 Prospect.swift:
class Prospects: ObservableObject { @Published var people: [Prospect] init() { self.people = [] } } 复制代码
我们稍后回来修改这个类。
现在,我们要让所有的 ProspectView
实例共享单一的 Prospects
实例,以便它们都指向相同的数据。如果我们还是采用 UIKit 编写代码,那我需要大费口舌来解释实现这一点有多么困难,以及我们在确保所有变化合理传播这件事时要多么当心,但在 SwiftUI 中,我们只需要三步。
首先,我们添加一个属性到 ContentView
,创建一个 Prospects
的单例:
var prospects = Prospects() 复制代码
其次,我们需要发送这个属性到 SwiftUI 的环境中,以便所有的子视图可以访问它。因为 tab 被看作是 tab view 的子视图,所以如果我们把这个属性添加到 TabView
的环境,那么所有的 ProspectsView
实例都将能够访问它。
把这个 modifier 添加到 ContentView
的 TabView
:
.environmentObject(prospects) 复制代码
接下来我们需要所有的 ProspectsView
在创建时从环境中读出这个对象。这里用到一个新的属性包装器,叫 @EnvironmentObject
。把下面这个属性添加到 ProspectsView
:
@EnvironmentObject var prospects: Prospects 复制代码
以上就是全部的步骤 —— 我想没有比这个更简单的方式了。
重要: 当你是用 @EnvironmentObject
的时候,你是在显式地告诉 SwiftUI ,当视图创建时你的对象会存在于环境中。如果它不存在,你的应用将会立即崩溃 —— 因此,请千万小心,把环境对象当成一个隐式的未解包的可选型来处理。
很快我们将要添加代码实现通过扫描二维码来添加 prospect 的功能,现在我们要先添加一个导航栏,用于添加测试数据。
把 ProspectsView
的 body
属性修改为这样:
NavigationView { Text("People: \(prospects.people.count)") .navigationBarTitle(title) .navigationBarItems(trailing: Button(action: { let prospect = Prospect() prospect.name = "Paul Hudson" prospect.emailAddress = "paul@hackingwithswift.com" self.prospects.people.append(prospect) }) { Image(systemName: "qrcode.viewfinder") Text("Scan") }) } 复制代码
现在你会在 ProspectsView
视图里看到一个 “扫描” 按钮,点击它,为三个视图同时添加一个人 —— 无论点的是哪个 tab 里的按钮,你都会看到 count 增加。
我的公众号 这里有Swift及计算机编程的相关文章,以及优秀国外文章翻译,欢迎关注~
这篇关于[SwiftUI 100 天] 用 @EnvironmentObject 在 tab 间共享数据的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-10-05Swift语法学习--基于协议进行网络请求
- 2022-08-17Apple开发_Swift语言地标注释
- 2022-07-24Swift 初见
- 2022-05-22SwiftUI App 支持多语种 All In One
- 2022-05-10SwiftUI 组件参数简写 All In One
- 2022-04-14SwiftUI 学习笔记
- 2022-02-23Swift 文件夹和文件操作
- 2022-02-17Swift中使用KVO
- 2022-02-08Swift 汇编 String array
- 2022-01-30SwiftUI3.0页面反向传值