macOS 13下SwiftUI Toolbar标题与按钮不显示问题求助
macOS 13下SwiftUI/AppKit混合开发Toolbar标题与按钮不显示的解决方法
我的应用在macOS 14、15上运行正常,但适配macOS 13时出现问题:Toolbar的标题和按钮完全不显示。以下是我采用AppKit/SwiftUI混合模式的原始代码,因需要精细窗口管理暂未迁移到SwiftUI App模式。
原始代码
@main class AppDelegate: NSObject, NSApplicationDelegate { var window: NSWindow? func applicationDidFinishLaunching(_ notification: Notification) { let view = SideBar() let contentView = NSHostingView(rootView: view) let window = NSWindow( contentRect: NSRect(origin: .zero, size: CGSize(width: 500, height: 400)), styleMask: [.titled, .unifiedTitleAndToolbar, .closable, .miniaturizable, .resizable, .fullSizeContentView], backing: .buffered, defer: false ) window.contentView = contentView window.toolbar = NSToolbar() window.center() window.makeKeyAndOrderFront(nil) self.window = window } } struct SideBar: View { var body: some View { NavigationView { NavigationLink(destination: ContentView()) { Text("Content") } } } } struct ContentView: View { var body: some View { HStack { Spacer() VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") } Spacer() } .padding() .navigationTitle("Test") .toolbar { ToolbarItem(placement: .automatic) { Button { } label: { Label("Add", systemImage: "plus") } } } } }
效果对比
macOS 15(预期效果)
macOS 13(问题表现)
问题原因
macOS 13中,SwiftUI的navigationTitle和toolbar需要与窗口的NSToolbar建立正确关联。直接创建空的NSToolbar()实例会导致SwiftUI无法识别并注入Toolbar内容,同时NSHostingView的约束配置也会影响Toolbar的渲染。
修复方案
修改以下几个关键部分:
- 给
NSHostingView添加自动调整大小的掩码,确保SwiftUI内容填满窗口 - 创建带唯一标识符的
NSToolbar,而非空实例,让SwiftUI能正确关联 - 明确设置
NavigationView的样式,适配macOS 13的导航视图逻辑 - 针对macOS 13配置统一Toolbar样式
修复后的完整代码
@main class AppDelegate: NSObject, NSApplicationDelegate { var window: NSWindow? func applicationDidFinishLaunching(_ notification: Notification) { let view = SideBar() let contentView = NSHostingView(rootView: view) // 让视图自动适配窗口大小 contentView.autoresizingMask = [.width, .height] let window = NSWindow( contentRect: NSRect(origin: .zero, size: CGSize(width: 500, height: 400)), styleMask: [.titled, .unifiedTitleAndToolbar, .closable, .miniaturizable, .resizable, .fullSizeContentView], backing: .buffered, defer: false ) window.contentView = contentView // 创建带标识符的Toolbar,允许SwiftUI关联内容 window.toolbar = NSToolbar(identifier: "MainWindowToolbar") window.toolbar?.allowsUserCustomization = false window.toolbar?.autosavesConfiguration = false // 适配macOS 13的统一Toolbar样式 if #available(macOS 13.0, *) { window.toolbarStyle = .unified } window.center() window.makeKeyAndOrderFront(nil) self.window = window } } struct SideBar: View { var body: some View { NavigationView { NavigationLink(destination: ContentView()) { Text("Content") } } // 明确设置导航视图样式,解决macOS 13兼容性问题 .navigationViewStyle(.columns) } } struct ContentView: View { var body: some View { HStack { Spacer() VStack { Image(systemName: "globe") .imageScale(.large) .foregroundStyle(.tint) Text("Hello, world!") } Spacer() } .padding() .navigationTitle("Test") .toolbar { ToolbarItem(placement: .automatic) { Button { } label: { Label("Add", systemImage: "plus") } } } } }
内容的提问来源于stack exchange,提问作者Lukas Würzburger
相关产品推荐
相关产品推荐

