swift - 将更改发布到可观察对象的集合
问题描述
我在传播视图模型中保存在数组中的对象上发生的更改时遇到问题。
我知道,@Published
如果集合本身发生变化(例如,如果元素struct
不是class
),集合将起作用。假设我需要将类保留为类。有没有办法将事件传播到视图,以便它知道应该刷新它。
我一直在尝试所有讨厌的方法,例如实施ObservableCollection
,ObservableArray
但似乎没有任何效果。
下面是我正在努力解决的一个例子。ObservableObject
Toggle 正在更改具有所有一致性和@Published
注释但仍然没有刷新 Text的数组的内部元素。
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()
}
}
解决方案
您的方法的问题是TextHolder是一个类,它是引用类型,如果您更改其中的任何值,更改将不会反映到数组,这就是 SwiftUI 视图未更新的原因。
方法一:
您可以将TextHolder从类更改为结构,如果您更改结构中的任何值,则会创建一个新副本,您的数组将获得更改为您的 SwiftUI 视图。
请尝试以下代码
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
}
}
方法二:
更改值后,您必须手动告诉您的viewModel某些内容已更改,请刷新。
Button("Toggle") {
vm.texts[0].toggle()
vm.objectWillChange.send()
}
希望能帮助你理解。
推荐阅读
- c# - 在 C# 中调用对话框任务?
- javascript - Restart iterating for loop from beginning once looping ends - JS
- uikit - 在 iOS 12 的 UIDatePicker 中自定义背景和文本颜色
- javascript - 增加另一个输入值时减少数字输入值
- spring - UriComponentsBuilder does not expand @Value properties
- apache-spark - Spark:并行读取具有不同架构的多个 AVRO 文件
- c# - JSON 文件和 LINQ 总和和组
- r - 当节点具有循环连接时,Igraph 保留具有最高权重的边
- aws-lambda - CloudFront Lambda@Edge HTTPS 重定向
- notepad++ - 删除哈希标签和注释记事本++