我正在尝试使用iOS 15.0 swipeActions
和confirmationDialog
删除List
中的项目。
但发生的是错误的项目被删除。
下面是我的代码:
struct ConversationsSection: View {
@State private var isShowingDeleteActions = false
let items = ["One", "Two", "Three", "Four", "Five"]
var body: some View {
List(items, id: \.self) { item in
Text(item)
.swipeActions(edge: .trailing) {
Button(role: .destructive) {
isShowingDeleteActions = true
print("Trying to delete: " + item)
} label: {
Label("Delete", systemImage: "trash")
}
}
.confirmationDialog("Delete item?", isPresented: $isShowingDeleteActions) {
Button("Confirm Delete", role: .destructive) {
print("Actually deleting: " + item)
isShowingDeleteActions = false
}
}
}
}
}
输出为:
Trying to delete: Two
Actually deleting: Four
Trying to delete: Five
Actually deleting: Three
所以我滑动一个项目,confirmationDialog
就出现了,但是在confirmationDialog
里面,另一个项目就通过了,为什么呢?
3条答案
按热度按时间i7uq4tfw1#
我是这样想的:在ForEach循环中有一个
confirmationDialog
修饰符,因此有多个确认对话框,它们的显示由一个$isShowingDeleteActions
状态变量控制。当这种情况发生时,SwiftUI无法可靠地从设置状态变量的循环示例中显示对话框-因此它可能最终显示一个 different 对话框,并且item
值不同。我知道这有多令人沮丧!
一种解决方法是将confirmationDialog完全移出循环,这样就只有一个修饰符使用
$isShowingDeleteActions
,问题是不再有对item
的直接引用,但是我们可以通过在第二个状态变量中保留一个引用来弥补:cx6n0qe32#
Scott的解决方案运行良好,但当你想在iPad上显示
confirmationDialog
时,附件被关闭(因为它现在使用List作为附件)。可以通过将
Text
及其修改器和@State
属性提取到新视图中来修复此问题,如下所示:本文截图:
p3rjfoxz3#
两种方式:
1.将“@State private var isPresented”、“.swipeActions”和“.confirmationDialog”放入列表项中,就像Esera's answer一样。但有一个问题,confirmationDialog经常在一秒钟内弹出并消失,然后在垃圾桶按钮单击之前的swipeActions时弹出。经过一些研究,我发现这是因为swipeActions-.destructive button。使用.none代替,一切都很好。请参见ConfirmationDialog 0。
1.使用@State私有变量选定消息:Int?= nil,在swipeActions中设置它,在confirmationDialog中使用它。问题是这个confirmationDialog for whole list,而不是for a list item,就像Esera's answer一样。
检查我的测试代码: