如何在SwiftUI应用生命周期下用纯SwiftUI模拟NSTitlebarAccessoryViewController控件外观
纯SwiftUI实现方案
你可以通过SwiftUI原生的工具栏修饰符直接实现和NSTitlebarAccessoryViewController完全一致的外观效果,无需桥接AppKit,核心是使用.accessoryBar类型的工具栏位置,系统会自动匹配原生标题栏附件的背景、间距和控件样式,具体实现如下:
1. 基础实现(适配SwiftUI 3+ / macOS 12+)
直接在你的内容视图上添加toolbar修饰符,指定位置为.accessoryBar即可:
@main struct SculptingApp: App { @StateObject private var model = DataModel() var body: some Scene { WindowGroup { SculptingView(model: model, undoManager: UndoManager()) .toolbar { // 附件工具栏,对应原来的NSTitlebarAccessoryViewController效果 ToolbarItem(placement: .accessoryBar(id: "ToolSettings")) { ToolAccessoryView(model: model) // 匹配原生工具栏控件的小尺寸 .controlSize(.small) } } // 统一工具栏样式,和系统窗口风格对齐 .windowToolbarStyle(.unified) } .windowStyle(.titleBar) } }
2. 低版本系统兼容方案(macOS 11及以下)
如果需要支持更低版本系统,可以自己手动模拟附件栏的样式,注意以下两点即可匹配原生外观:
- 背景使用系统磨砂材质,不要用纯色
- 所有控件使用小尺寸的原生样式
struct MainView: View { var model: DataModel var undoManager: UndoManager var body: some View { VStack(spacing: 0) { // 自定义工具条 HStack(spacing: 8) { ToolAccessoryView(model: model) .controlSize(.small) } .padding(.horizontal, 12) .padding(.vertical, 6) // 匹配原生标题栏附件的磨砂背景 .background(.ultraThinMaterial) // 延伸到窗口左右边缘 .frame(maxWidth: .infinity) SculptingView(model: model, undoManager: undoManager) } .ignoresSafeArea(.container, edges: .top) } }
3. 控件样式调整
如果你的Slider等控件还是和原生样式有差异,可以额外添加修饰符对齐:
Slider(value: $model.brushSize) .controlSize(.small) // 匹配AppKit原生滑块的外观风格 .tint(.accentColor)
内容的提问来源于stack exchange,提问作者Taylor
相关产品推荐
相关产品推荐

