SwiftUI macOS工具栏被内容元素遮挡,应如何正确配置?
问题原因
你遇到的工具栏被遮挡、仅hover时可交互的问题由两个错误用法导致:
toolbar修饰符挂载位置错误:你当前将它加在了NavigationView内部的HStack内容子视图上,工具栏和子视图平级,会被同层级的内容视图覆盖交互区域。- 隐藏标题栏后内容视图无顶部避让:使用
HiddenTitleBarWindowStyle后,内容视图默认会撑满整个窗口包括顶部工具栏区域,完全覆盖了工具栏的响应范围。
解决方法
按以下步骤修改代码即可修复:
- 将
toolbar修饰符从HStack移动到NavigationView上,保证工具栏层级高于所有内部内容视图,不会被遮挡。 - 给NavigationView添加
.toolbarStyle(.unified)修饰符,适配隐藏标题栏的窗口样式,保证工具栏布局正常。 - 若不需要内容背景延伸到工具栏下方,可给HStack添加顶部内边距避开工具栏区域,参考值可读取当前窗口的标题栏高度。
修改后的完整代码如下:
import SwiftUI import AppKit @main struct TestApp: App { var body: some Scene { WindowGroup { NavigationView { List { Text("One") Text("Two") } .listStyle(.sidebar) HStack { Text("Hello, world!") .background(Color.gray) .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) } .padding(.all, 1) // 可选:添加顶部内边距避开工具栏区域,不需要沉浸式背景可保留 .padding(.top, NSApplication.shared.mainWindow?.titlebarHeight ?? 28) } // toolbar移到NavigationView层级 .toolbar { ToolbarItemGroup(placement: .navigation) { Button(action: { NSApp.keyWindow?.firstResponder?.tryToPerform(#selector(NSSplitViewController.toggleSidebar(_:)), with: nil) }, label: { Image(systemName: "sidebar.left") .imageScale(.large) }) } } // 适配隐藏标题栏的工具栏样式 .toolbarStyle(.unified) } .windowStyle(HiddenTitleBarWindowStyle()) } }
如果需要实现内容背景延伸到工具栏下方的沉浸式效果,删除HStack的顶部padding即可,工具栏因为层级更高,依然可以正常响应交互。
内容的提问来源于stack exchange,提问作者MagicCarpetPilot
相关产品推荐
相关产品推荐

