我正在尝试使用 an@EnvironmentObject
来跟踪几个对象数组的 Bool 状态,但是我遇到了超出范围的索引并且无法弄清楚原因。
我正在尝试跟踪在三个容器之间进行选择的“查询”。每个容器都有一组“框架”,我需要切换这些框架并更改按钮标签的颜色:
import SwiftUI
class Query: ObservableObject {
@Published var selectedContainer: Int = 2
@Published var frames: [Bool] = [true, true, true, true, true, true, true, true]
func resetFrames() {
switch selectedContainer {
case 0:
self.frames = [true, true, true, true, true]
print("Boxes")
case 1:
self.frames = [true, true, true]
print("Bags")
case 2:
self.frames = [true, true, true, true, true, true, true, true]
print("Barrels")
default:
self.frames = [true, true, true]
}
}
func satisfiedFrames() {
let shouldReset = frames.allSatisfy { $0 == false }
print(shouldReset)
if shouldReset == true {
resetFrames()
}
}
}
enum Container {
case box
case bag
case barrel
var tag: Int {
switch self {
case .box:
return 0
case .bag:
return 1
case .barrel:
return 2
}
}
var name: String {
switch self {
case .box:
return "Box"
case .bag:
return "Bag"
case .barrel:
return "Barrel"
}
}
}
我也有我的颜色在一个数组中:
let dvColors: [Color] = [
Color.red,
Color.orange,
Color.yellow,
Color.green,
Color.blue,
Color.indigo,
Color.purple,
Color.pink
]
然后我有一个选择器可以像这样在容器之间切换:
@EnvironmentObject var query: Query
var container: [Container] = [.box, .bag, .barrel]
var body: some View {
Picker(selection: $query.selectedContainer, label: Text("Container")){
ForEach(0..<container.count) { index in
Text(self.container[index].name)
.tag(index)
}
}
.onChange(of: query.selectedContainer, perform: changeContainer)
}
func changeContainer(_ tag: Int) {
print("CHANGE CONTAINER ON PICKER")
print("TAG: \(tag)")
query.selectedContainer = tag
print("QUERY CONTAINER: \(query.selectedContainer)")
query.resetFrames()
print("FRAMES COUNT: \(query.frames.count)")
}
}
最后,这是我的内容视图:
import SwiftUI
struct ContentView: View {
@StateObject var query = Query()
var body: some View {
NavigationView {
ZStack {
ScrollView {
Text("FRAME COUNT: \(query.frames.count)")
Text("Container: \(query.selectedContainer)")
Spacer()
}
.navigationBarTitleDisplayMode(.inline)
.toolbar(){
ToolbarItem(placement: .principal, content: {
ContainerPicker()
})
}
VStack {
Spacer()
TheHStack()
}
}
}
.environmentObject(query)
}
}
struct TheHStack: View {
@EnvironmentObject var query: Query
var body: some View {
print(query.frames)
return HStack (spacing: 10) {
ForEach(query.frames.indices, id: \.self) { value in
ColouredText(value: value)
}
}
}
}
struct ColouredText: View {
@EnvironmentObject var query: Query
var value: Int
var body: some View {
Button(action: {
query.frames[value].toggle()
print(query.frames)
print("\(value)")
}, label: {
Text("\(value + 1)")
.foregroundColor(query.frames[value] ? dvColors[value] : .gray) // THIS LINE FAILS, I GUESS WHEN LOOKING UP THE COLOUR?
})
}
}
我期望做的是,当我使用选择器进行选择时,容器的布尔值都设置为 TRUE。然后点击按钮切换该容器中的框架。并且当使用选择器选择另一个容器时,新容器的框架都是 TRUE。此外,如果所有布尔值都变为 FALSE,则它们会自动重置为全部 TRUE。
如果我将三元颜色更改为一种颜色,一切正常。我的打印语句显示了正确的更改。但我无法让 UI 正确更新。