为什么警告对话框在 SwiftUI 中删除了错误的项目?

Why alert dialog delete the wrong item in SwiftUI?

我的 SwiftUI 项目有问题,我正在尝试使用警报对话框删除列表中的项目,但是当使用 .alert 时,删除了错误的项目。我还是不知道我错过了什么?

这是我的代码:

struct CustomView: View {
    @State private var selectedUsers: CustomModel?
    @State var users: [CustomModel]
    @State private var selectDelete = false
    var body: some View {
        ScrollView(.vertical, showsIndicators: false, content: {  
            VStack(content: {
                ForEach(users){ user in
                    CustomRowView(user: user)
                        .contextMenu {
                            Button(action: {
                                self.delete(item: data)
                            }) {
                                Text("remove") 
                            }
                        }
                        .onTapGesture {
                            selectedUsers = user
                        }
                        .alert(isPresented: $selectDelete) {
                            Alert(title: Text("title"),
                                message: Text("message"),
                                primaryButton: .destructive(Text("Delete")) {
                                    self.delete(item: user)
                                },
                                secondaryButton: .cancel()
                            )
                        }
                        .onDelete { (indexSet) in
                            self.users.remove(atOffsets: indexSet)
                        }
                }
            })
        })
    }

    private func delete(item user: CustomModel) {
        if let index = users.firstIndex(where: { [=10=].id == user.id }) {
            users.remove(at: index)
        }
    }
}

型号:

struct CustomModel: Identifiable{
var id = UUID().uuidString
var name: String
}

var users = [

CustomModel(name: "david"),
CustomModel(name: "marry"),
CustomModel(name: "henry"),
CustomModel(name: "nadi"), ]

您的代码中有 2 个问题导致了意外行为:

  1. 当您使用 ForEach 遍历用户时,您会为每个实例附加一个 .alert() 修饰符。这意味着,当 selectDelete 设置为 true 时, 所有 实例都会尝试显示警报,但只有一个会。哪一个?谁知道,但那个实例将被删除。

  2. 你有一个很好的 selectedUsers 变量,当你点击它时它会发生变化。但是您删除的是 user,而不是 selectedUser

如何通过 3 个步骤修复代码以使用 .alert()

  • 如果您不需要使用点击手势执行任何任务,只需将其删除并更改上下文菜单中的 selectedUser
.contextMenu {
    Button(action: {

    selectedUsers = user    // Change here then delete

    self.delete(item: data)
}) {
    Text("remove") }}

    // Forget about it...
    //.onTapGesture {
    //    selectedUsers = user
    //}
  • 将您的警报附加到视图的 top-most 级别(在底部):
ScrollView {
    ...
}
.alert(isPresented: $selectDelete) {
    ...
}
  • 删除 selectedUser,而不是 user:
self.delete(item: selectedUser)