You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 14:05:02