SwiftUI桌面应用:如何完全移除含交通灯的标题栏?
完全移除SwiftUI macOS应用的窗口标题栏(含交通灯按钮)
HiddenTitleBarWindowStyle()仅会隐藏标题文字,但仍保留交通灯按钮和标题栏的占位区域,要彻底移除整个标题栏,需要通过自定义NSWindow实例来实现,具体步骤如下:
1. 自定义NSWindow子类
创建一个继承自NSWindow的类,通过修改样式掩码完全移除标题栏相关元素:
import Cocoa class CustomBorderlessWindow: NSWindow { override init(contentRect: NSRect, styleMask style: NSWindow.StyleMask, backing backingStoreType: NSWindow.BackingStoreType, defer flag: Bool) { // 使用borderless样式,同时保留可调整大小、全屏内容视图的能力 let customStyle: NSWindow.StyleMask = [.borderless, .resizable, .fullSizeContentView] super.init(contentRect: contentRect, styleMask: customStyle, backing: backingStoreType, defer: flag) // 确保内容视图占满整个窗口,禁止标题栏相关显示 titlebarAppearsTransparent = true titleVisibility = .hidden isMovableByWindowBackground = true // 允许通过窗口背景拖动窗口 } }
2. 在AppDelegate中手动创建自定义窗口
通过NSApplicationDelegate拦截应用启动流程,替换默认窗口为自定义窗口:
class AppDelegate: NSObject, NSApplicationDelegate { // 应用关闭最后一个窗口后自动退出 func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { return true } func application(_ application: NSApplication, didFinishLaunchingWithOptions launchOptions: [NSApplication.LaunchOptionsKey : Any]? = nil) { // 关闭默认创建的窗口 application.windows.forEach { $0.close() } // 创建自定义窗口并关联SwiftUI视图 let contentView = MainView() let window = CustomBorderlessWindow( contentRect: NSRect(x: 0, y: 0, width: 800, height: 600), styleMask: [.borderless, .resizable, .fullSizeContentView], backing: .buffered, defer: false ) window.contentView = NSHostingView(rootView: contentView) window.center() // 窗口居中显示 window.makeKeyAndOrderFront(nil) } }
3. 修改@main结构体
移除原有的WindowGroup(因为窗口已通过AppDelegate手动创建):
@main struct MyApp: App { @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate var body: some Scene { // 若需要设置窗口,可保留Settings;无需则直接移除 Settings { SettingsView() } } }
可选:添加自定义控制按钮
如果需要窗口的关闭、最小化功能,可在MainView中手动实现按钮,调用系统API完成操作:
struct MainView: View { var body: some View { ZStack { // 你的应用内容 Color.white .ignoresSafeArea() // 自定义控制按钮组(示例) VStack { HStack { Button(action: { NSApplication.shared.terminate(nil) }) { Image(systemName: "xmark") .foregroundColor(.gray) } Button(action: { NSApplication.shared.windows.first?.miniaturize(nil) }) { Image(systemName: "minus") .foregroundColor(.gray) } Spacer() } .padding(.top, 16) .padding(.leading, 16) Spacer() } } } }
内容的提问来源于stack exchange,提问作者Perch Hakobyan
相关产品推荐
相关产品推荐

