我希望不在 macOS 上显示 SwiftUI 应用程序的窗口。该应用程序使用 SwiftUI 的应用程序生命周期,并且仅在状态栏中运行。启动时显示窗口是不必要的。然而我不确定如何绕过
WindowGroup
。不存在 EmptyScene
这样的东西,将 EmptyView
放入 WindowGroup
中当然会创建一个空窗口。
@main
struct MyApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
我基本上只需要应用程序委托。我猜使用默认的 AppKit 生命周期更有意义,但如果有一种方法可以使用 SwiftUI 的生命周期,我很想知道。
在您的 AppDelegate 中,在 applicationDidFinishLaunching 中执行以下操作:
func applicationDidFinishLaunching(_ notification: Notification) {
// Close main app window
if let window = NSApplication.shared.windows.first {
window.close()
}
// Code continues here...
}
例如:
class AppDelegate: NSObject, NSApplicationDelegate {
var popover = NSPopover.init()
var statusBar: StatusBarController?
func applicationDidFinishLaunching(_ notification: Notification) {
// Close main app window
if let window = NSApplication.shared.windows.first {
window.close()
}
// Create the SwiftUI view that provides the contents
let contentView = ContentView()
// Set the SwiftUI's ContentView to the Popover's ContentViewController
popover.contentSize = NSSize(width: 160, height: 160)
popover.contentViewController = NSHostingController(rootView: contentView)
// Create the Status Bar Item with the above Popover
statusBar = StatusBarController.init(popover)
}
}
该应用程序使用 SwiftUI 的应用程序生命周期并且仅在状态栏中运行。
MenuBarExtra
场景以使用本机 SwiftUI 生命周期在系统菜单栏中呈现持久控件。 (Xcode 14.2、macOS Ventura)
@main
struct MyStatubarMenuApp: App {
var body: some Scene {
// -- no WindowGroup required --
// -- no AppDelegate needed --
MenuBarExtra {
Text("Hello Status Bar Menu!")
MyCustomSubmenu()
Divider()
Button("Quit") { NSApp.terminate(nil) }
} label: {
Image(systemName: "bolt.fill")
}
}
}
备注:
Application is agent = YES
中添加 Info.plist
并将应用程序图标设置为 不在 Dock 上显示。systemName:
当 System Settings…
> Appearance
更改时,SF 符号将自动切换外观。@Environment(\.colorScheme)
当前不在应用程序/场景级别更新如果您的应用程序有设置(谁没有?),您可以这样做:
@main
struct TheApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
Settings {
SettingsView()
}
}
}
你应该能够做这样的事情:
var body: some Scene {
WindowGroup {
ZStack {
EmptyView()
}
.hidden()
}
}
var body: some Scene {
WindowGroup{
EmptyView()
.frame(width: 0, height: 0)
.hidden()
}
.windowResizability(.contentSize)
}
窗口可调整大小 (_:) 在 macOS 13+ 上可用