swift - @ObservableObject 的 Swift 链
问题描述
在我的 Swift 项目中,数据和触发数据变化的前端按钮由几层对象隔开。如何使前端视图反映删除了几层的更改?我想这是 Swift 开发中相当普遍的情况。
这是一个工作示例,视图和数据之间没有分隔层。
import Foundation
import SwiftUI
import OrderedCollections
class Test: ObservableObject {
@Published var array: [String] = []
var num: Int = 0
func add() {
array.append(String(num))
num += 1
}
}
struct testView: View {
@ObservedObject var test = Test()
var body: some View {
VStack {
Button(action: { test.add() }) {
Text("Add Item to Array")
}
Text("")
Text("Items")
Text(Array(test.array).description)
}
}
}
@main
struct app: App {
var body: some Scene {
WindowGroup {
testView()
}
}
}
这是一个不起作用的“中间”类的示例。
class Test: ObservableObject {
@Published var array: [String] = []
var num: Int = 0
func add() {
array.append(String(num))
num += 1
}
}
class Middle: ObservableObject {
@ObservedObject var test: Test = Test()
}
struct testView: View {
@ObservedObject var m = Middle()
var body: some View {
VStack {
Button(action: { m.test.add() }) {
Text("Add Item to Array")
}
Text("")
Text("Items")
Text(Array(m.test.array).description)
}
}
}
@main
struct app: App {
var body: some Scene {
WindowGroup {
testView()
}
}
}
注意:使用其他代码,我似乎已经能够让我的视图更新远离前端的变化数据。我确信这是可能的——我正在寻找的是使这项工作的系统方法(我目前的方法只是将@ObservableObject、@Published 和@ObservedObject 添加到数据接触的所有内容中,直到它工作——或不工作' t)。
解决方案
可能有一些元素很好理解。最重要的是:
属性包装器
@ObservedObject
用于在一个内部使用——如果在另一个内部View
使用它不会做任何事情ObservableObject
@Published
只有在使用值类型时才能开箱即用。在 Swift 中,这意味着使用struct
s 而不是class
es。
关于第二点,除非有真正令人信服的理由不这样做,否则您的模型应该是struct
s。这意味着您可以只使用一个@Published
属性来存储它们,一切都会正常工作:
struct Test {
var array: [String] = []
var num: Int = 0
}
class Middle: ObservableObject {
@Published var test: Test = Test()
func append() {
test.array.append(String(test.num))
test.num += 1
}
}
如果由于某种原因您必须使用嵌套对象,则必须objectWillChange.send()
手动调用以告诉您的 SwiftUIView
该@Published
属性有新数据:
class Test : ObservableObject {
var array: [String] = []
var num: Int = 0
func append() {
array.append(String(num))
num += 1
}
}
class Middle: ObservableObject {
@Published var test: Test = Test()
func append() {
test.append()
self.objectWillChange.send()
}
}
您还可以搜索“SwiftUI 嵌套的 ObservableObject”,这将为您提供有关此主题的大量现有对话,包括:
推荐阅读
- postgresql - 无法通过 PG-Promise 初始化 Postgresql 数据库
- python - Word 表中的文本
- python - 使用 for 循环在 pandas 中附加多个数据帧
- php - 表列的两个内部连接到不同的表
- php - 将主题应用于 Yii2 高级应用程序
- apache-spark - 在 Clojure Flambo api 调用中进行 DataFrame 查找时无法获得结果
- javascript - 不能用“null”覆盖背景色
- php - 在输入字段中隐藏 html 值
- three.js - 填充边界问题,具有堆叠透明纹理的 360 场景中的低 fps
- java - 如何将参数添加到 Spring Batch 项目阅读器?