我正在尝试使用 iOS 15.0swipeActions并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
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
}
输出是:
Trying to delete: Two
Actually deleting: Four
Trying to delete: Five
Actually deleting: Three
Run Code Online (Sandbox Code Playgroud)
所以我滑动一个项目并confirmationDialog显示出来。但里面confirmationDialog又传递了另一个项目。这是为什么?
我是这样想的:confirmationDialogForEach 循环中有一个修饰符,因此有多个确认对话框,其显示由单个$isShowingDeleteActions状态变量控制。发生这种情况时,SwiftUI 无法可靠地显示设置状态变量 \xe2\x80\x93 的循环实例中的对话框,因此它最终可能会显示不同的对话框,并且其item值不同。
我明白这是多么令人沮丧!
\n一种解决方法是将确认对话框完全移出循环,因此只有一个修饰符使用$isShowingDeleteActions. 问题在于不再直接引用item,但我们可以通过在第二个状态变量中保留引用来进行补偿:
struct ConversationsSection: View {\n\n@State private var isShowingDeleteActions = false\n@State private var itemToDelete: Item? = nil\n\nvar body: some View {\n List(items, id: \\.self) { item in\n Text(item)\n .swipeActions(edge: .trailing) {\n Button(role: .destructive) {\n itemToDelete = item\n isShowingDeleteActions = true\n } label: {\n Label("Delete", systemImage: "trash")\n }\n }\n }\n .confirmationDialog("Delete item?", isPresented: $isShowingDeleteActions) {\n Button("Confirm Delete", role: .destructive) {\n if let item = itemToDelete {\n print("Actually deleting: " + item)\n isShowingDeleteActions = false\n itemToDelete = nil\n }\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n
Scott 的解决方案工作正常,但是当您想在 iPad 上显示 时confirmationDialog,附件会关闭(因为它现在使用列表作为附件)。请参阅下面的屏幕截图:
您可以通过将Text及其修饰符和属性一起提取@State到新视图中来解决此问题,如下所示:
import SwiftUI
struct ItemView: View {
@State private var isShowingDeleteActions = false
var item: String
var body: some View {
Text(item)
.frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
.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
}
}
}
}
struct ConversationsSection: View {
let items = ["One", "Two", "Three", "Four", "Five"]
var body: some View {
NavigationView {
List(items, id: \.self) { item in
ItemView(item: item)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
截图如下:
| 归档时间: |
|
| 查看次数: |
1880 次 |
| 最近记录: |