SwiftUI中.contextMenu切换Bool值后按钮文本未更新如何解决
问题原因
SwiftUI 的 .contextMenu 会在所属视图首次渲染时预生成菜单内容,后续状态变更时默认不会触发菜单的重建,因此修改 active 字段后,已生成的上下文菜单文本不会自动更新。
解决方案
给挂载 .contextMenu 的视图添加 .id() 修饰符,将 item.active 作为标识的一部分,只要该值发生变化,SwiftUI 就会销毁旧视图、重新渲染新视图,同步重新生成最新的上下文菜单。
同时建议将 ForEach 遍历改为绑定遍历,避免手动查找索引带来的强制解包风险,修改后的完整代码如下:
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) ] var body: some View { List { // 改为绑定遍历,直接拿到元素的可修改引用 ForEach($items) { $item in VStack { Text("\(item.user)") HStack { Text("Active ? ") Text(item.active ? "YES": "NO") } } // 新增id修饰符,active变化时触发视图重绘刷新contextMenu .id(item.active) .contextMenu{ Button(action: { // 直接通过绑定修改状态,无需手动查找索引 item.active.toggle() }) { Text(item.active ? "设为未激活": "设为已激活") } } } } } }
上述方案实现成本最低,对原有业务逻辑几乎无侵入。如果不想修改视图标识,也可将上下文菜单内容单独封装为接收状态绑定的子视图,同样能实现菜单的自动更新。
内容的提问来源于stack exchange,提问作者unknown
相关产品推荐
相关产品推荐

