当另一个视图上的数据更改时,我想更新概述视图上的UI元素。
我研究了@EnvironmentalObject和@Binding。但是,对这两个对象的更新似乎都不会强制重新加载视图。仅更改@State force renders。
另外,在以下情况下,ChangeView也不是OverviewView的子级。因此,@ Binding仍然不是一个选择。
Data.swift
struct ExampleData : Hashable {
var id: UUID
var name: String
}
var globalVar: ExampleData = ExampleData(id: UUID(), name:"")
OverviewView.swift
struct OverviewView: View {
@State private var data: ExampleData = globalVar
var body: some View {
Text(data.name)
}
}
ChangeView.swift
struct ChangeView: View {
@State private var data: ExampleData = globalVar
var body: some View {
TextField("Name", text: $data.name, onEditingChanged: { _ in
globalVar = data }, onCommit: { globalVar = data })
}
}
ChangeView TextField中的更改将更新globalVar。但是,切换回视图时,这不会更新OverviewView上的Text。
我知道使用全局变量是“丑陋”的编码。如何处理将在众多无关视图中使用的数据?
请提供有关如何更好地处理这种情况的建议。
答案 0 :(得分:2)
OverviewView
和ChangeView
在其data
变量中拥有ExampleData结构的不同副本(将结构分配给另一个变量时,实际上是在复制它,而不是像对象。)因此更改其中一个不会影响另一个。
@EnvironmentObject适合您的要求。
这是一个例子:
由于我们正在使用@EnvironmentObject,因此您需要将ExampleData
转换为
一个类,或使用一个类来存储它。我将使用后者。
class ExampleDataHolder: ObservableObject {
@Published var data: ExampleData = ExampleData(id: UUID(), name:"")
}
struct CommonAncestorOfTheViews: View {
var body: some View {
CommonAncestorView()
.environmentObject(ExampleDataHolder())
}
}
struct OverviewView: View {
@EnvironmentObject var dataHolder: ExampleDataHolder
var body: some View {
Text(dataHolder.data.name)
}
}
struct ChangeView: View {
@EnvironmentObject var dataHolder: ExampleDataHolder
var body: some View {
TextField("Name", text: $dataHolder.data.name)
}
}