Ventura 13.3.1下Mac Catalyst的SwiftUI菜单图片标签失效问题
升级Ventura 13.3.1后,Mac Catalyst对Menu组件的样式逻辑做了调整,原来靠.buttonStyle(.plain)实现的自定义图片触发菜单的方式会被系统强制覆盖,只显示默认下拉箭头。以下是两个可行的解决办法:
方案一:自定义MenuStyle(贴近原生行为)
通过自定义MenuStyle,把Menu的触发逻辑完全交给自定义的Plain Button,这样就能保留你的图片样式,同时沿用原生Menu的交互逻辑(比如键盘导航、系统动画)。
// 定义自定义MenuStyle struct CustomImageMenuStyle: MenuStyle { func makeBody(configuration: Configuration) -> some View { Button(action: configuration.trigger) { configuration.label } .buttonStyle(.plain) } } // 使用自定义样式的Menu Menu { Button("first button") { // 这里写你的操作逻辑 } Button("second button") { // 这里写你的操作逻辑 } } label: { Image(systemName: "arrow.up.arrow.down.circle") .resizable() .scaledToFit() .foregroundColor(Color("SSGreen")) .frame(width: scaleForMac(int: 34), height: scaleForMac(int: 34), alignment: .center) } .menuStyle(CustomImageMenuStyle())
方案二:用Button+Popover模拟Menu(完全自定义)
如果自定义MenuStyle还是达不到预期,你可以用Button触发Popover的方式模拟下拉菜单,完全掌控外观和交互逻辑:
@State private var isMenuPopoverShown = false var body: some View { Button { isMenuPopoverShown.toggle() } label: { Image(systemName: "arrow.up.arrow.down.circle") .resizable() .scaledToFit() .foregroundColor(Color("SSGreen")) .frame(width: scaleForMac(int: 34), height: scaleForMac(int: 34), alignment: .center) } .buttonStyle(.plain) // 弹出Popover模拟下拉菜单,箭头方向设为底部 .popover(isPresented: $isMenuPopoverShown, arrowEdge: .bottom) { VStack(spacing: 0) { Button("first button") { // 操作逻辑 isMenuPopoverShown = false } .frame(minWidth: 150, minHeight: 32) .padding(.horizontal, 8) Button("second button") { // 操作逻辑 isMenuPopoverShown = false } .frame(minWidth: 150, minHeight: 32) .padding(.horizontal, 8) } .padding(4) .background(Color.white) .cornerRadius(6) .shadow(radius: 2) } }
方案对比
- 方案一:保留原生Menu的所有系统特性,代码更简洁,适合需要原生交互体验的场景。
- 方案二:完全自定义菜单外观,不受系统样式限制,但需要手动处理菜单的关闭逻辑和布局细节。
内容的提问来源于stack exchange,提问作者AxelB
相关产品推荐
相关产品推荐

