警报在 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?")
}
警报应该从模型中移除对象,但是当出现警报时,值与点击和长按手势中的值不同。知道为什么吗?
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?")
}