斯威夫特用户界面 [这是列表和我的按钮的代码]
ForEach(items, id: \.self) { current in
VStack(alignment: .leading) {
Text("\(current.task)")
.padding(2)
Text("\(dateFormatter.string(from: current.date))")
Button(action: {},
label: {
Image(systemName:
"checkmark.rectangle.fill")
.resizable()
.frame(width: 50, height: 35)
})
}
Items 是我的数组,包含一个字符串和一个日期。这是它的代码:
@State var items:[Tasks] = [Tasks(task: "Test", date: Date())]
这是任务:
struct Tasks: Hashable {
let task: String
let date: Date
}
我想让用户能够单击每个列表项下的按钮,它将删除该列表项。我目前正在使用 onDelete 方法,但我希望在每个列表项中都有一个确认按钮,允许用户删除该列表项。
@State var counter = -1
我尝试使用一个每次 ForEach 循环运行时都会增加 1 的计数器,并在 ForEach 循环内创建一个等于它的新变量。但是我无法访问按钮内部的变量以用作索引。
使用您当前的代码结构,假设每个 task: String
都是唯一的,您可以将其添加到您的 Button
操作中:
Button(action: {
if let index = items.firstIndex(where: {$0.task == current.task}) {
items.remove(at: index)
}
},
label: {
Image(systemName: "checkmark.rectangle.fill")
.resizable()
.frame(width: 50, height: 35)
})
但是,将 id
属性添加到您的 Task
会更稳健,并且
同时重命名它,因为 Swift 已经将 Task
定义为其 async/await 框架的一部分。
这是我用来测试我的答案的完整代码:
struct MyTask: Identifiable, Hashable { // <--- here
let id = UUID() // <--- here
let task: String
let date: Date
}
struct ContentView: View {
@State var items:[MyTask] = [
MyTask(task: "Test1", date: Date()),
MyTask(task: "Test2", date: Date().addingTimeInterval(60*60*24*44)),
MyTask(task: "Test3", date: Date().addingTimeInterval(60*60*24*88))
]
var body: some View {
ForEach(items) { current in // <--- here
VStack(alignment: .leading) {
Text(current.task).padding(2) // <--- here
Text(dateFormatter.string(from: current.date)) // <--- here
Button(action: {
// --- here
if let index = items.firstIndex(where: {$0.id == current.id}) {
items.remove(at: index)
}
},
label: {
Image(systemName: "checkmark.rectangle.fill").resizable()
.frame(width: 50, height: 35)
})
}
}
}
var dateFormatter: DateFormatter = {
let frmt = DateFormatter()
frmt.dateFormat = "yyyy-MMM-dd"
return frmt
}()
}