英文:
How would I delete items from a list with a button inside that list?
问题
SwiftUI
[这是列表和按钮的代码]
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: "测试", date: Date())]
这是 Tasks 结构体:
struct Tasks: Hashable {
let task: String
let date: Date
}
我希望用户能够点击每个列表项下面的按钮,以删除该列表项。我目前使用 onDelete 方法,但我更希望在每个列表项下面有一个确认按钮,允许用户删除该列表项。
@State var counter = -1
我尝试使用一个计数器,使其在 ForEach 循环运行时递增,并在该 ForEach 循环内创建一个等于计数器值的新变量。然而,我无法在按钮内访问该变量以用作索引。
英文:
SwiftUI
[This is the code for the list and my button]
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 is my array containing a string and a date. Here is the code for it:
@State var items:[Tasks] = [Tasks(task: "Test", date: Date())]
And here is Tasks:
struct Tasks: Hashable {
let task: String
let date: Date
}
I want to have a user be able to click a button under each list item and it will remove that list item. I am currently using the onDelete method but I would prefer to have a confirm button in each list item that would allow the user to remove that list item.
@State var counter = -1
I tried using a counter that would increase by 1 each time the ForEach loop ran and create a new variable inside of that ForEach loop equal to it. However I could not access the variable inside of the button to use as an index.
答案1
得分: 1
根据您当前的代码结构,假设每个 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)
})
然而,为了使代码更加健壮,建议为您的 Task
添加一个 id
属性,并同时重命名它,因为Swift已经将 Task
定义为其异步/等待框架的一部分。
以下是我用于测试我的答案的完整代码:
struct MyTask: Identifiable, Hashable {
let id = UUID()
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
VStack(alignment: .leading) {
Text(current.task).padding(2)
Text(dateFormatter.string(from: current.date))
Button(action: {
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
}()
}
请注意,我已经将 HTML 实体(例如 <
和 "
)转换为正常的Swift代码。
英文:
Using your current code structure, assuming each task: String
is unique, you could just add this to your Button
action:
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)
})
However, it would be more robust to add an id
property to your Task
, and
at the same time rename it, because Swift already defines Task
as part of its async/await framework.
Here is the complete code I use to test my answer:
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
}()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论