首页 > 解决方案 > onDeleteCommand 菜单项始终启用

问题描述

我正在将 macOS Monterey Beta 5 与 Xcode 13 Beta 5 一起使用,但onDeleteCommand. 基本上,即使没有选择任何项目,它的菜单项也不会禁用。

我试过deleteDisabled了,但它没有帮助。

以下是如何重现:

  1. 创建一个新的空白 SwiftUI macOS 项目
  2. 粘贴以下代码:
struct ContentView: View {
    @State var data = ["Item1", "Item2", "Item3"]
    @State var selection: Set<String> = []
    
    var body: some View {
        NavigationView {
            List(data, id: \.self, selection: $selection) { item in
                Text(item)
            }
            .onDeleteCommand {
                data.removeAll(where: selection.contains) // Removes selected items
                selection.removeAll()
            }
            .deleteDisabled(selection.isEmpty) // This doesn't help either
            Text("Second Panel")
        }
    }
}
  1. 运行应用程序,然后选择一个项目。
  2. 转到菜单,然后按编辑 -> 删除。现在选定的项目应该消失了,但编辑 -> 删除菜单项仍处于启用状态。

我能做些什么来解决这个问题(让菜单项自行禁用)?

任何帮助将不胜感激。

标签: swiftmacosswiftui

解决方案


文档没有说明这一点(我提交了一份报告),但您可以将nil操作作为操作传递给大多数(全部?)on*Command(perform:)修饰符以显式禁用关联的菜单项。这个稍微重写ContentView的应该得到正确的行为:

struct ContentView: View {
    @State var data = ["Item1", "Item2", "Item3"]
    @State var selection: Set<String> = []

    var body: some View {
        NavigationView {
            List(data, id: \.self, selection: $selection) { item in
                Text(item)
            }
            .onDeleteCommand(perform: selection.isEmpty ? nil : deleteSelection)
            Text("Second Panel")
        }
    }

    private func deleteSelection() {
        data.removeAll { selection.contains($0) }
        selection.removeAll()
    }
}

虽然效果可能与接受的答案基本相同,但传递nil而不是动作块通常是一种更可靠的方法,因为视图身份的更改有时会产生令人惊讶的后果。


推荐阅读