在ForEach视图中添加和删除按钮



这是我的代码:

ForEach(StaffList, id: .self) { item in
HStack {
Text("(item)")
Spacer(minLength: 0)
Image(systemName: "x.circle")
.foregroundColor(.red)
.onTapGesture {
//TODO: Remove user UUID from array + Show add button
}
Image(systemName: "checkmark.circle")
.foregroundColor(.blue)
.onTapGesture {
//TODO: Add user UUID from array + Show remove button
}
}
}

一个简单的解决方案是在Struct中为循环中的每一个变量设置一个@state变量,但这会产生问题。因为每个按钮都分配给同一个变量。当变量发生变化时,所有变量都会发生变化。例如:


@State var isShowing = false

ForEach(StaffList, id: .self) { item in
HStack {
Text("(item)")
Spacer(minLength: 0)
if isShowing {
Image(systemName: "x.circle")
.foregroundColor(.red)
.onTapGesture {
//TODO: Remove user UUID from array + Show add button
is Showing = true
}
} else {
Image(systemName: "checkmark.circle")
.foregroundColor(.blue)
.onTapGesture {
//TODO: Add user UUID from array + Show remove button
isShowing = false
}
}
}
}

从技术上讲,这是可行的,但考虑到StaffList中的人数不受限制。如果我在其中一个上单击X,它们都会更新为显示Checkmark。目标是ForEach,如果从那以后,他们都有自己的一套改变。因此,当我在其中一个循环上单击X时,它会更新并显示Checkmark,但ForEach循环中没有其他循环更新,并且仍然显示X

编辑 在问题的最新更新后,以下是解决问题的正确答案"按钮对于所有项目而不是对于每个单个项目都在改变">

可以使用@State变量隐藏或显示按钮。网上有几个教程。

但是,要分别更改StaffList的每个成员的按钮(我们最好将其称为staffList,因为它是一个变量(,您需要为ForEach中的每个项目设置一个@State变量。这可以通过创建一个辅助视图来实现,在下面的示例中,我称之为ItemView

这是代码:

struct YourMainView: View {
// This is not the right place for the @State variable that affects each single item
// @State var isShowing = false
// Other variable declarations
var body: some View {
ForEach(staffList, id: .self) { item in
ItemView(item: item)
}
}
}
// This is the view of each single item
struct ItemView: View {
let item: StaffListItemType    // Whatever the actual type is
// Here is the right place to manage it (always make it private)
@State private var isShowing = false
var body: some View {
HStack {
Text("(item)")
Spacer(minLength: 0)
if isShowing {
Image(systemName: "x.circle")
.foregroundColor(.red)
.onTapGesture {
//TODO: Remove user UUID from array + Show add button
isShowing = false  // If it's true, it needs to become false. Or, use .toggle()
}
} else {
Image(systemName: "checkmark.circle")
.foregroundColor(.blue)
.onTapGesture {
//TODO: Add user UUID from array + Show remove button
isShowing = true  // If it's false, it needs to become true. Or, use .toggle()
}
}
}
}
}

最新更新