出于某种原因,我不明白,当我从 a 添加/删除项目@State var
时MainView
,OutterView
s 没有正确更新。
我想要实现的是用户一次只能“标记”(选择)一个项目。例如,当我点击“item #1”时,它会被标记。如果我单击另一个项目,则“项目 #1”将不再被标记,而只会标记我刚刚单击的新项目。
目前,我的代码显示所有项目,就好像它们已被标记一样,即使它们不再存在。以下代码具有我为MainView
、OutterView
和实现的最小结构和功能InnerView
。
我尝试使用State var
s 而不是 in 中的计算属性OutterView
,但它不起作用。另外,我尝试使用 avar
而不是计算属性 inOutterView
并将其初始化,init()
但也不起作用。
希望你能帮助我找出我做错了什么。谢谢!
struct MainView: View {
@State var flagged: [String] = []
var data: [String] = ["item #1", "item #2", "item #3", "item #4", "item #5"]
var body: some View {
VStack(spacing: 50) {
VStack {
ForEach(data, id:\.self) { text in
OutterView(text: text, flag: flagged.contains(text)) { (flag: Bool) in
if flag {
flagged = [text]
} else {
if let index = flagged.firstIndex(of: text) {
flagged.remove(at: index)
}
}
}
}
}
Text("Flagged: \(flagged.description)")
Button(action: {
flagged = []
}, label: {
Text("Reset flagged")
})
}
}
}
struct OutterView: View {
@State private var flag: Bool
private let text: String
private var color: Color { flag ? Color.green : Color.gray }
private var update: (Bool)->Void
var body: some View {
InnerView(color: color, text: text)
.onTapGesture {
flag.toggle()
update(flag)
}
}
init(text: String, flag: Bool = false, update: @escaping (Bool)->Void) {
self.text = text
self.update = update
_flag = State(initialValue: flag)
}
}
struct InnerView: View {
let color: Color
let text: String
var body: some View {
Text(text)
.padding()
.background(
Capsule()
.fill(color))
}
}