SwiftUI 中的上下文菜单未更新

Posted

技术标签:

【中文标题】SwiftUI 中的上下文菜单未更新【英文标题】:Context Menu not updating in SwiftUI 【发布时间】:2021-11-29 18:15:20 【问题描述】:

我正在尝试设置一个 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$0.user == item.user
                        
                        items[index!].active.toggle()
                    ) 
                        Text(item.active ? "Set as Active": "Set as Inactive")
                    
                
            
        
    

【问题讨论】:

【参考方案1】:

这是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:  $0.id == item.id ) 
                    items[index].active.toggle()
                
            
        
        .id(item.id)
    

【讨论】:

以上是关于SwiftUI 中的上下文菜单未更新的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI上下文菜单(Context Menu)内容不随对象状态刷新的解决

SwiftUI嵌入在Form或Section中的视图上下文菜单(contextMenu)无法独立弹出的解决

WPF CommandParameter 在上下文菜单中设置时未更新

SwiftUI 上下文菜单是不是使用 LayoutConstraints?

通过左键单击 macOS 触发 SwiftUI 上下文菜单

如何将上下文菜单应用于 SwiftUI 表格行?