如何使用可绑定对象(EnviromentObject)?
How to use BindableObjects (EnviromentObject)?
我正在使用新的 SwiftUI。我有一个 UserUpdate
class,它是一个 Bindable Object
,我想修改这些变量并自动更新 UI。
我成功更新了这些值,但是当我更改 UserUpdate
class 中的变量时,我的 UI 结构中的视图没有更新。
当我修改 UI 结构本身中的 @EnviromentObject
变量时,它 仅 发生变化。
那是我的可绑定对象 Class:
final class UserUpdate: BindableObject {
let didChange = PassthroughSubject<Any, Never>()
var allUsers: [User] = [] {
didSet {
print(allUsers)
didChange.send(allUsers)
}
}
var firstName: String = "" {
didSet {
didChange.send(firstName)
}
}
var lastName: String = "" {
didSet {
didChange.send(lastName)
}
}
}
那是我的用户 class:
struct User: Identifiable {
let id: Int
let firstName, lastName: String
}
以下是我配置 UI 的方式:
struct ContentView : View {
@EnvironmentObject var bindableUser: UserUpdate
var body: some View {
NavigationView {
VStack(alignment: .leading) {
Text("All Users:").bold().padding(.leading, 10)
List {
ForEach(bindableUser.allUsers) { user in
Text("\(user.firstName) \(user.lastName)")
}
}
}
}
}
}
这里我修改UserUpdate
中的变量:
class TestBind {
static let instance = TestBind()
let userUpdate = UserUpdate()
func bind() {
let user = User(id: userUpdate.allUsers.count, firstName: "Heyy", lastName: "worked")
userUpdate.allUsers.append(user)
}
}
我发现我必须从我的 UI 调用该方法才能使其正常工作,因此它在同一流上。
例如:
struct ContentView : View {
@EnvironmentObject var networkManager: NetworkManager
var body: some View {
VStack {
Button(action: {
self.networkManager.getAllCourses()
}, label: {
Text("Get All Courses")
})
List(networkManager.courses.identified(by: \.name)) {
Text([=10=].name)
}
}
}
}
如果我没记错的话,你应该在你的 ContentView
中注入 UserUpdate
实例,可能在 SceneDelegate
中,使用 ContentView().environmentObject(UserUpdate())
.
在这种情况下,您有 2 个不同的 UserUpdate
class 实例,第一个在 SceneDelegate
中创建,第二个在 TestBind
中创建class.
问题是您有一个绑定到视图的实例(并将在更新时触发视图重新加载),而您实际修改的实例(在 TestBind
class 中)是与观点完全无关。
您应该找到在视图和 TestBind
class 中使用 相同实例 的方法(例如通过使用 ContentView().environmentObject(TestBind.instance.userUpdate)
我正在使用新的 SwiftUI。我有一个 UserUpdate
class,它是一个 Bindable Object
,我想修改这些变量并自动更新 UI。
我成功更新了这些值,但是当我更改 UserUpdate
class 中的变量时,我的 UI 结构中的视图没有更新。
当我修改 UI 结构本身中的 @EnviromentObject
变量时,它 仅 发生变化。
那是我的可绑定对象 Class:
final class UserUpdate: BindableObject {
let didChange = PassthroughSubject<Any, Never>()
var allUsers: [User] = [] {
didSet {
print(allUsers)
didChange.send(allUsers)
}
}
var firstName: String = "" {
didSet {
didChange.send(firstName)
}
}
var lastName: String = "" {
didSet {
didChange.send(lastName)
}
}
}
那是我的用户 class:
struct User: Identifiable {
let id: Int
let firstName, lastName: String
}
以下是我配置 UI 的方式:
struct ContentView : View {
@EnvironmentObject var bindableUser: UserUpdate
var body: some View {
NavigationView {
VStack(alignment: .leading) {
Text("All Users:").bold().padding(.leading, 10)
List {
ForEach(bindableUser.allUsers) { user in
Text("\(user.firstName) \(user.lastName)")
}
}
}
}
}
}
这里我修改UserUpdate
中的变量:
class TestBind {
static let instance = TestBind()
let userUpdate = UserUpdate()
func bind() {
let user = User(id: userUpdate.allUsers.count, firstName: "Heyy", lastName: "worked")
userUpdate.allUsers.append(user)
}
}
我发现我必须从我的 UI 调用该方法才能使其正常工作,因此它在同一流上。
例如:
struct ContentView : View {
@EnvironmentObject var networkManager: NetworkManager
var body: some View {
VStack {
Button(action: {
self.networkManager.getAllCourses()
}, label: {
Text("Get All Courses")
})
List(networkManager.courses.identified(by: \.name)) {
Text([=10=].name)
}
}
}
}
如果我没记错的话,你应该在你的 ContentView
中注入 UserUpdate
实例,可能在 SceneDelegate
中,使用 ContentView().environmentObject(UserUpdate())
.
在这种情况下,您有 2 个不同的 UserUpdate
class 实例,第一个在 SceneDelegate
中创建,第二个在 TestBind
中创建class.
问题是您有一个绑定到视图的实例(并将在更新时触发视图重新加载),而您实际修改的实例(在 TestBind
class 中)是与观点完全无关。
您应该找到在视图和 TestBind
class 中使用 相同实例 的方法(例如通过使用 ContentView().environmentObject(TestBind.instance.userUpdate)