MacOS SwiftUI应用:实现仅菜单栏启动,阻止主窗口打开
SwiftUI macOS菜单栏应用消除启动空白主窗口方案
背景
开发基于SwiftUI的macOS应用,需求是仅通过菜单栏启动,不打开空白主窗口,同时保留通知功能。
问题
应用启动时,菜单栏图标显示正常,但会自动打开一个空白主窗口,不符合预期。
已尝试操作
移除var body部分或删除Settings{}代码块,但实现App协议时这两项为必填项,会触发编译错误。
核心代码上下文(Quote_DropletApp.swift)
以下是控制窗口启动的唯一核心文件代码:
class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDelegate { static private(set) var instance: AppDelegate! lazy var statusBarItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) let menu = ApplicationMenu() func applicationDidFinishLaunching(_ notification: Notification) { AppDelegate.instance = self statusBarItem.button?.image = NSImage(named: NSImage.Name("QuoteDropletSmall")) statusBarItem.button?.imagePosition = .imageLeading statusBarItem.menu = menu.createMenu() // 自动启动逻辑 let mainAppIdentifier = "com.Daggerpov.Quote-Droplet" let runningApps = NSWorkspace.shared.runningApplications let isRunning = !runningApps.filter { $0.bundleIdentifier == mainAppIdentifier }.isEmpty if !isRunning { var pathComponents = (Bundle.main.bundlePath as NSString).pathComponents pathComponents.removeLast() pathComponents.removeLast() pathComponents.removeLast() pathComponents.removeLast() let newPath = NSString.path(withComponents: pathComponents) NSWorkspace.shared.launchApplication(newPath) } UNUserNotificationCenter.current().delegate = self UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { success, error in if success { NotificationScheduler.shared.scheduleNotifications() } else if let error { print(error.localizedDescription) } } } }
解决方案
方案一:通过Info.plist设置后台运行
在项目的Info.plist中添加LSUIElement键,设置值为YES。此配置会让应用以纯菜单栏后台应用运行,不会显示Dock图标和默认主窗口。
方案二:在SwiftUI App结构体中禁用默认窗口
若需保留Dock图标但启动时不显示主窗口,修改App结构体代码如下:
@main struct Quote_DropletApp: App { @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate var body: some Scene { // 用空视图的WindowGroup避免自动创建主窗口 WindowGroup { EmptyView() } .windowStyle(.hiddenTitleBar) // 可选:彻底隐藏窗口样式 // 保留Settings场景但用空视图避免显示设置窗口,或替换为自定义设置UI Settings { EmptyView() } } }
注意点
- 方案一设置后,应用不会出现在Cmd+Tab切换列表中,若需支持应用切换,优先选方案二。
- 确保
AppDelegate中的自动启动逻辑不会重复触发窗口创建。
内容的提问来源于stack exchange,提问作者Daggerpov
相关产品推荐
相关产品推荐

