警报在 LazyVGrid SwiftUI 中采用了错误的值

Alert is taking wrong values inside LazyVGrid SwiftUI

警报应该从模型中移除对象,但是当出现警报时,值与点击和长按手势中的值不同。知道为什么吗?

LazyVGrid(columns: columns, spacing: 5) {
            ForEach(model.robotsRepository.robots) { robot in
                RobotView(model: RobotView.Model(robotsRepository: model.robotsRepository, robot: robot)).environmentObject(team)
                    .contentShape(Rectangle())
                    .alert(isPresented: $showAlert) {
                        //When Alert is apearing, "robot" value are not the same as a value inside tap and longPress Gesture
                        Alert(
                            title: Text("Remove Card"),
                            message: Text("Are you sure you want to remove this card?"),
                            primaryButton: .destructive(Text("Remove")) {
                                withAnimation {
                                    model.remove(robot: robot)
                                }
                            },
                            secondaryButton: .cancel() {
                                withAnimation {
                                    deleting = false
                                }
                            }
                        )
                    }
                    .onTapGesture {
                        addRobot(robot: robot, at: selectedIndex)
                    }
                    .onLongPressGesture {
                        withAnimation {
                            showAlert = true
                            deleting = true
                        }
                    }
            }
        }

您可以尝试将 .alert(isPresented: $showAlert) {...} 移出 ForEach,并且可能移出 LazyVGrid 也是。例如这样的东西(未经测试):

@State var selectedRobot = Robot.default  // <--- here adjust accordingly

LazyVGrid(columns: columns, spacing: 5) {
            ForEach(model.robotsRepository.robots) { robot in
                RobotView(model: RobotView.Model(robotsRepository: model.robotsRepository, robot: robot)).environmentObject(team)
                    .contentShape(Rectangle())
                    .onTapGesture {
                        addRobot(robot: robot, at: selectedIndex)
                    }
                    .onLongPressGesture {
                        withAnimation {
                            selectedRobot = robot  // <-- here
                            showAlert = true
                            deleting = true
                        }
                    }
            }
        }
        .alert(isPresented: $showAlert) {
            Alert(
                title: Text("Remove Card"),
                message: Text("Are you sure you want to remove this card?"),
                primaryButton: .destructive(Text("Remove")) {
                    withAnimation {
                        model.remove(robot: selectedRobot) // <-- here
                    }
                },
                secondaryButton: .cancel() {
                    withAnimation {
                        deleting = false
                    }
                }
            )
        }
     

EDIT-1:请注意 alert(isPresented:content:) alert(item:content:) 已弃用(iOS 13.0–15.4)。

如果你正在使用 (ios15+) 你可以使用下面的方法 (根据 Apple 示例:https://developer.apple.com/documentation/swiftui/view/alert(_:ispresented:presenting:actions:message:)-8584l

// for demonstration
struct Robot: Identifiable {
    let id = UUID()
    let name: String = "no name"
}

.....

@State var selectedRobot: Robot?  // <--- here

 .....

        LazyVGrid(columns: columns, spacing: 5) {
            ForEach(model.robotsRepository.robots) { robot in
                RobotView(model: RobotView.Model(robotsRepository: model.robotsRepository, robot: robot)).environmentObject(team)
                    .contentShape(Rectangle())
                    .onTapGesture {
                        addRobot(robot: robot, at: selectedIndex)
                    }
                    .onLongPressGesture {
                        withAnimation {
                            selectedRobot = robot  // <-- here
                            showAlert = true
                            deleting = true
                        }
                    }
            }
        }
        .alert("Remove Card", isPresented: $showAlert, presenting: selectedRobot) { robot in
            Button(role: .destructive) {
                withAnimation {
                    model.remove(robot: robot) 
                }
            } label: { Text("Remove") }
            
            Button(role: .cancel) {
                withAnimation {
                    deleting = false
                }
            } label: { Text("Cancel") }
            
        } message: { _ in
            Text("Are you sure you want to remove this card?")
        }