小屏幕下ToolbarItem合并菜单点击无响应问题求助
解决SwiftUI ToolbarItem合并菜单点击无响应问题
问题描述
在SwiftUI中给topBarTrailing位置添加5个ToolbarItem后,小屏设备或系统字体放大时,会有2-3个项被自动合并成一个菜单项,但点击该合并项无法弹出预期弹窗,调试器抛出报错:
Called -[UIContextMenuInteraction updateVisibleMenuWithBlock:] while no context menu is visible. This won't do anything.
测试代码如下:
struct ToolBarBugTest: View { var body: some View { Button(action: {}, label: { Text("Tap Me") }) .padding() .navigationTitle("My Navigation") .toolbar { ToolbarItem(placement: .topBarTrailing) { Button { print("Tapped") } label : { Image(systemName: "eye") } } ToolbarItem(placement: .topBarTrailing) { // same as above } ToolbarItem(placement: .topBarTrailing) { // same as above } ToolbarItem(placement: .topBarTrailing) { // same as above } ToolbarItem(placement: .topBarTrailing) { // same as above } } } }
尝试使用NavigationView时,系统不会生成合并菜单,只会持续添加ToolbarItem。
解决方法
这个问题是SwiftUI自动合并ToolbarItem时的已知交互异常,可通过以下方式修复:
1. 手动用Menu包裹多余项
放弃系统自动合并逻辑,手动将部分项放入Menu中,确保菜单交互稳定:
struct ToolBarFixed: View { var body: some View { Button(action: {}, label: { Text("Tap Me") }) .padding() .navigationTitle("My Navigation") .toolbar { // 保留2个直接显示的ToolbarItem ToolbarItem(placement: .topBarTrailing) { Button { print("Tapped eye") } label : { Image(systemName: "eye") } } ToolbarItem(placement: .topBarTrailing) { Button { print("Tapped star") } label : { Image(systemName: "star") } } // 将剩余项放入Menu ToolbarItem(placement: .topBarTrailing) { Menu { Button { print("Tapped heart") } label: { Label("Like", systemImage: "heart") } Button { print("Tapped share") } label: { Label("Share", systemImage: "square.and.arrow.up") } Button { print("Tapped settings") } label: { Label("Settings", systemImage: "gear") } } label: { Image(systemName: "ellipsis.circle") } } } } }
2. 使用ToolbarItemGroup分组
把所有ToolbarItem放入ToolbarItemGroup中,让系统更合理地处理布局与合并逻辑,避免交互异常:
struct ToolBarFixedWithGroup: View { var body: some View { Button(action: {}, label: { Text("Tap Me") }) .padding() .navigationTitle("My Navigation") .toolbar { ToolbarItemGroup(placement: .topBarTrailing) { Button { print("Tapped eye") } label : { Image(systemName: "eye") } Button { print("Tapped star") } label : { Image(systemName: "star") } Button { print("Tapped heart") } label : { Image(systemName: "heart") } Button { print("Tapped share") } label : { Image(systemName: "square.and.arrow.up") } Button { print("Tapped settings") } label : { Image(systemName: "gear") } } } } }
空间不足时,ToolbarItemGroup会自动将多余项合并为菜单,且交互逻辑比单独的ToolbarItem更稳定。
3. NavigationView适配(iOS 16及以前)
若使用NavigationView,需指定StackNavigationViewStyle并配合ToolbarItemGroup触发合并:
NavigationView { ToolBarFixedWithGroup() } .navigationViewStyle(StackNavigationViewStyle())
内容的提问来源于stack exchange,提问作者Muhammad Bilal
相关产品推荐
相关产品推荐

