我在传播保存在数组中的 View 模型中的对象发生的更改时遇到问题。
我明白 @Published
如果集合本身发生变化(例如,如果元素是 struct
而不是 class
),则集合会起作用。假设我需要将类保留为类。有没有办法将事件传播到 View ,以便它知道应该刷新它。
我一直在尝试所有讨厌的方法,比如实现 ObservableCollection
或 ObservableArray
但似乎没有任何效果。
下面是我正在努力解决的一个例子。
Toggle 正在更改具有所有 ObservableObject
的数组的内部元素一致性和 @Published
注释,但仍然没有刷新文本。
import SwiftUI
import Combine
struct ContentView: View {
@StateObject var vm = ViewModel()
var body: some View {
Text(vm.texts.first!.text)
.padding()
Button("Toggle") {
vm.texts.first?.toggle()
}
}
}
class ViewModel: ObservableObject {
@Published var texts: [TextHolder] = [.init(), .init()]
}
class TextHolder: ObservableObject {
@Published var text: String = ""
func toggle() {
text = UUID().uuidString
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
最佳答案
您的方法的问题在于 文本支架 是一个类,它是引用类型,如果您更改其中的任何值,更改将不会反射(reflect)到数组,这就是 SwiftUI View 未更新的原因。
方法一:
您可以更改 文本支架 从类到结构,如果您更改结构中的任何值,则会创建一个新副本,您的数组将更改为您的 SwiftUI View 。
请尝试以下代码
struct ContentView: View {
@StateObject var vm = ViewModel()
var body: some View {
Text(vm.texts.first!.text)
.padding()
Button("Toggle") {
vm.texts[0].toggle()
}
}
}
class ViewModel: ObservableObject {
@Published var texts: [TextHolder] = [.init(), .init()]
}
struct TextHolder {
var text: String = ""
mutating func toggle() {
text = UUID().uuidString
}
}
方法二:更改值后,您必须手动告诉您的 View 模型 东西变了,请刷新。
Button("Toggle") {
vm.texts[0].toggle()
vm.objectWillChange.send()
}
希望能帮助你理解。
关于swift - 发布对可观察对象集合的更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68103063/