在SwiftUI中数据传递非常的简单,方便理解的话,我们可以简单的把数据传递理解为一次传递使用@ObservedObject,二次及以上传递使用@EnvironmentObject。这只是一个理解方式,并不是原理。

创建数据类

我们可以新建一个数据类,这个类用来调用我们的数据结构体和一些常用的函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import Foundation

class UserData {
var userList: [User]

init(userList: [User]) {
self.userList = userList
}
}

struct User {
var name: String
var age: Int
}

这是一个简单的类包含结构。接下来我们需要在类上继承ObservableObject超类。

1
2
3
//...
class UserData: ObservableObject {
//...

调用数据类

在视图中我们可以直接使用这个数据类

1
2
3
4
5
6
7
8
9
10
11
12
import SwiftUI

struct SwiftUIView: View {
@ObservedObject var userData = UserData(userList: [
User(name: "小明", age: 18),
User(name: "小绿", age: 19)
])

var body: some View {
Text("Hello, World!")
}
}

这样在userData变化的时候,会同步到数据类的变化。那么我们如何再将我们初始化好的UserData类传递到第三个视图呢?

使用@EnvironmentObject

在多次调用的时候我们需要使用@EnvironmentObject将数据传递下去。例如我们的视图包含了另外的视图。

1
2
3
4
5
6
7
8
9
10
11
12
13
//SwiftUIView
import SwiftUI

struct SwiftUIView: View {
@ObservedObject var userData = UserData(userList: [
User(name: "小明", age: 18),
User(name: "小绿", age: 19)
])

var body: some View {
SwiftUIView2()
}
}

我们想让SwiftUIView2中的内容展示SwiftUIView中的初始化好的userData。这个时候我们就用到了@EnvironmentObject。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//SwiftUIView2
import SwiftUI

struct SwiftUIView2: View {
@EnvironmentObject var userData: UserData

var body: some View {
VStack {
ForEach(0 ..< userData.userList.count) { item in
Text("\(userData.userList[item].name) 现在 \(userData.userList[item].age) 岁了")
}
}
}
}

然后我们需要编辑SwiftUIView,告诉SwiftUIView2他的userData是什么数据。

1
2
3
4
5
//SwiftUIView
//...
SwiftUIView2()
.environmentObject(userData)
//...

调试问题

在使用预览的时候我们也需要传递一个默认值供预览

1
2
3
4
5
6
7
//SwiftUIView2
struct SwiftUIView2_Previews: PreviewProvider {
static var previews: some View {
SwiftUIView2()
.environmentObject(UserData(userList: [User(name: "小花", age: 13)]))
}
}

大功告成

@ObservedObject和@EnvironmentObject是SwiftUI的特色数据传输方式,也是非常简单好用的方式。善用属性包装器可以更好的帮助你开发app。

源码

Data.swift

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import Foundation

class UserData: ObservableObject {
var userList: [User]

init(userList: [User]) {
self.userList = userList
}
}

struct User {
var name: String
var age: Int
}

SwiftUIView.swift

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import SwiftUI

struct SwiftUIView: View {
@ObservedObject var userData = UserData(userList: [
User(name: "小明", age: 18),
User(name: "小绿", age: 19)
])

var body: some View {
SwiftUIView2()
.environmentObject(userData)
}
}

struct SwiftUIView_Previews: PreviewProvider {
static var previews: some View {
SwiftUIView()
}
}

SwiftUIView2.swift

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import SwiftUI

struct SwiftUIView2: View {
@EnvironmentObject var userData: UserData

var body: some View {
VStack {
ForEach(0 ..< userData.userList.count) { item in
Text("\(userData.userList[item].name) 现在 \(userData.userList[item].age) 岁了")
}
}
}
}

struct SwiftUIView2_Previews: PreviewProvider {
static var previews: some View {
SwiftUIView2()
.environmentObject(UserData(userList: [User(name: "小花", age: 13)]))
}
}