修改环境对象,清除 SwiftUI 上另一个环境对象的数据
Modifying an environment object, clear data from another one on SwiftUI
我正在查看两个环境对象。我正在显示其中一个的数据,并修改另一个的数据。当我更改第一个对象的数据时,将创建第二个对象的另一个实例并清除其数据。
我创建了一个重现该问题的代码示例,如果您 运行 在预览时点击增量按钮两次,您将看到 列表为空!
列表只在onAppear
块加载,在计数器更新后创建视图时不会再次调用。
struct ContentView: View {
@EnvironmentObject var appState: AppState
var body: some View {
VStack {
View1()
.environmentObject(ListWrapper())
}
}
}
struct View1: View {
@EnvironmentObject var listWrapper: ListWrapper
@EnvironmentObject var appState: AppState
var body: some View {
VStack {
HStack {
Text("Counter:")
Text("\(appState.counter)")
}
HStack {
Button("+") { appState.increment() }.padding(.horizontal, 20)
Divider()
Button("-") { appState.decrement() }.padding(.horizontal, 20)
}.overlay(Rectangle().stroke(Color.accentColor))
.frame(height: 30)
List {
if listWrapper.list.count == 0 {
Text("List is empty!")
} else {
ForEach(listWrapper.list, id:\.self) {
Text([=10=])
}
}
}
}.onAppear { listWrapper.load() }
}
}
class ListWrapper: ObservableObject {
@Published var list: [String] = []
func load() { list = ["1", "2", "3"] }
}
class AppState: ObservableObject {
@Published var counter: Int = 0
func increment() { counter += 1 }
func decrement() { counter -= 1 }
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(AppState())
}
}
谁能解释一下问题出在哪里以及如何解决?
环境对象必须由祖先视图提供! >>> 转到 >>> 窗口组
ContentView()
.environmentObject(AppState()) // << Here: 1
.environmentObject(ListWrapper()) // << Here: 2
struct View1: View {
@EnvironmentObject var listWrapper: ListWrapper
@EnvironmentObject var appState: AppState
var body: some View {
VStack {
HStack {
Text("Counter:")
Text("\(appState.counter)")
}
HStack {
Button("+") {
appState.increment()
listWrapper.list.append(appState.counter.description) // << Here: 3
}.padding(.horizontal, 20)
Divider()
Button("-") {
appState.decrement()
listWrapper.list.append(appState.counter.description) // << Here: 4
}.padding(.horizontal, 20)
}
.overlay(Rectangle().stroke(Color.accentColor))
.frame(height: 30)
List {
if listWrapper.list.count == 0 {
Text("List is empty!")
}
else {
ForEach(listWrapper.list, id:\.self) { item in
Text(item)
}
}
}
}.onAppear { listWrapper.load() }
}
}
我正在查看两个环境对象。我正在显示其中一个的数据,并修改另一个的数据。当我更改第一个对象的数据时,将创建第二个对象的另一个实例并清除其数据。
我创建了一个重现该问题的代码示例,如果您 运行 在预览时点击增量按钮两次,您将看到 列表为空!
列表只在onAppear
块加载,在计数器更新后创建视图时不会再次调用。
struct ContentView: View {
@EnvironmentObject var appState: AppState
var body: some View {
VStack {
View1()
.environmentObject(ListWrapper())
}
}
}
struct View1: View {
@EnvironmentObject var listWrapper: ListWrapper
@EnvironmentObject var appState: AppState
var body: some View {
VStack {
HStack {
Text("Counter:")
Text("\(appState.counter)")
}
HStack {
Button("+") { appState.increment() }.padding(.horizontal, 20)
Divider()
Button("-") { appState.decrement() }.padding(.horizontal, 20)
}.overlay(Rectangle().stroke(Color.accentColor))
.frame(height: 30)
List {
if listWrapper.list.count == 0 {
Text("List is empty!")
} else {
ForEach(listWrapper.list, id:\.self) {
Text([=10=])
}
}
}
}.onAppear { listWrapper.load() }
}
}
class ListWrapper: ObservableObject {
@Published var list: [String] = []
func load() { list = ["1", "2", "3"] }
}
class AppState: ObservableObject {
@Published var counter: Int = 0
func increment() { counter += 1 }
func decrement() { counter -= 1 }
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(AppState())
}
}
谁能解释一下问题出在哪里以及如何解决?
环境对象必须由祖先视图提供! >>> 转到 >>> 窗口组
ContentView()
.environmentObject(AppState()) // << Here: 1
.environmentObject(ListWrapper()) // << Here: 2
struct View1: View {
@EnvironmentObject var listWrapper: ListWrapper
@EnvironmentObject var appState: AppState
var body: some View {
VStack {
HStack {
Text("Counter:")
Text("\(appState.counter)")
}
HStack {
Button("+") {
appState.increment()
listWrapper.list.append(appState.counter.description) // << Here: 3
}.padding(.horizontal, 20)
Divider()
Button("-") {
appState.decrement()
listWrapper.list.append(appState.counter.description) // << Here: 4
}.padding(.horizontal, 20)
}
.overlay(Rectangle().stroke(Color.accentColor))
.frame(height: 30)
List {
if listWrapper.list.count == 0 {
Text("List is empty!")
}
else {
ForEach(listWrapper.list, id:\.self) { item in
Text(item)
}
}
}
}.onAppear { listWrapper.load() }
}
}