上下文菜单未在 SwiftUI 中更新

Context Menu not updating in SwiftUI

我正在尝试设置一个 SwiftUI .contextMenu,带有一个切换 Bool 值的按钮。上下文菜单的按钮文本应该在 Bool 切换时更改。但是上下文菜单不会更新。有没有办法强制更新上下文菜单?

描述问题的示例代码:

import SwiftUI

struct Item: Identifiable {
    let id = UUID()
    let user: String
    var active: Bool
}

struct ContentView: View {
    @State var items: [Item] = [
        Item(user: "Daniel",active: false),
        Item(user: "Jack", active: true),
        Item(user: "John", active: true)
    ]
    
    @State var isOn : Bool = false
    var body: some View {
        List {
            ForEach(items) { item in
                VStack {
                    Text("\(item.user)")
                        
                    HStack {
                        Text("Active ? ")
                        Text(item.active ? "YES": "NO")
                    }
                }.contextMenu{
                    Button(action: {
                        let index = items.firstIndex{[=10=].user == item.user}
                        
                        items[index!].active.toggle()
                    }) {
                        Text(item.active ? "Set as Active": "Set as Inactive")
                    }
                }
            }
        }
    }
}

这是SwiftUI的一个bug,在Xcode 13.2 beta 2的模拟器中还是坏的

我设法通过在 if item.active 语句的两个分支中复制列表项来解决这个问题,如下所示:

struct ContentView: View {
    @State var items: [Item] = [
        Item(user: "Daniel",active: false),
        Item(user: "Jack", active: true),
        Item(user: "John", active: true)
    ]

    var body: some View {
        List {
            ForEach(items) { item in
                // work around SwiftUI bug where
                // context menu doesn't update
                if item.active { listItem(for: item) }
                else { listItem(for: item) }
            }
        }
    }

    private func listItem(for item: Item) -> some View {
        VStack {
            Text("\(item.user)")

            HStack {
                Text("Active ? ")
                Text(item.active ? "YES": "NO")
            }
        }
        .contextMenu {
            Button(item.active ? "Deactivate" : "Activate") {
                if let index = items.firstIndex(where: { [=10=].id == item.id }) {
                    items[index].active.toggle()
                }
            }
        }
        .id(item.id)
    }
}