如何从列表中删除列表中带有按钮的项目?

问题描述 投票:0回答:1

斯威夫特用户界面 [这是列表和我的按钮的代码]

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 
}

This is my list view

我想让用户能够单击每个列表项下的按钮,它将删除该列表项。我目前正在使用 onDelete 方法,但我希望在每个列表项中都有一个确认按钮,允许用户删除该列表项。

    @State var counter = -1 

我尝试使用一个每次 ForEach 循环运行时都会增加 1 的计数器,并在 ForEach 循环内创建一个等于它的新变量。但是我无法访问按钮内部的变量以用作索引。

arrays list swiftui
1个回答
0
投票

使用您当前的代码结构,假设每个 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
    }()
}
© www.soinside.com 2019 - 2024. All rights reserved.