SwiftUI- 调用中缺少参数 'at' 的参数

SwiftUI- Missing argument for parameter 'at' in call

我正在关注 CoreData tutorial 并想从列表中删除项目。对于 iPhone 在这种情况下将是 .onDelete(perform: deleteBudget) 滑动和删除。

但我正在为 macOS 开发,使用 .contextMenu 右键单击​​并删除。

我在 contextMenu 内的按钮中的 deleteBudget() 旁边收到此错误:

Missing argument for parameter 'at' in call

我不确定要包含在 'at' 中的正确参数。

内容视图

@ObservedObject private var budgetListVML: BudgetListViewModel

     init(vm: BudgetListViewModel){
                self.budgetListVML = vm
            }
        
   

 private func deleteBudget(at offsets: IndexSet) {
        offsets.forEach { index in
                let budget = budgetListVML.budgets[index]
                budgetListVML.deleteBudget(budgetId: budget.id)
            }
        

  List{
        ForEach(budgetListVML.budgets) { budget in
               NavigationLink{....
                }
               .contextMenu { 
                        Button {
                            deleteBudget()
                        } label: {
                            Text("Delete Budget")
                        }
                }
        }
            
  }

BudgetListViewModel

class BudgetListViewModel:NSObject, ObserverableObject {
@Published var budgets = [BudgetViewModel]()
.......
    func deleteBudget(budgetId: NSManagedObjectID){
        do {
            guard let budget = try context.existingObject(with: budgetId) as? Budget else {
                return
        }
        try budget.delete()
        
    } catch {
        print(error)
    }
}
....
}

 struct BudgetViewModel: Identifiable {
    private var budget: Budget
    
    init(budget: Budget) {
        self.budget = budget
    }


    var id: NSManagedObjectID {
        budget.objectID
          }

    var name: String {
        budget.name ?? ""
          }
       }

您的 deleteBudget 函数在其定义中有一个 at 参数:

private func deleteBudget(at offsets: IndexSet) {
                          ^^ <--- Here

这在使用时很有用,例如 ListonDelete 传递 IndexSet.

对于您的用例,如果您在 contextMenu 中没有 IndexSet,我建议制作一个采用 BudgetdeleteBudget 函数直接:

private func deleteBudget(_ budget : Budget) {
   budgetListVML.deleteBudget(budget)
}

并在您的 contextMenu 中调用:

.contextMenu { 
   Button {
     deleteBudget(budget)
   } label: {
     Text("Delete Budget")
   }
}

并且在您的视图模型中:

func deleteBudget(_ budget: Budget){
    do {
      try budget.delete()
    } catch {
      print(error)
    }
}