我正在创建一个使用
WindowGroup
和 MenuBarExtra
的 MacOS SwiftUI 应用程序,并且 MenuBarExtra
有一个菜单选项来启动我的应用程序。它利用深度链接允许 URL
加载 WindowGroup
,然后我的 ContentView
出现。但是,如果我从菜单栏项目多次启动应用程序,则会出现多个 WindowGroups
。
我想停止启动多个视图,只需启动该视图(如果该视图已关闭)或将现有视图置于前面(如果该视图已打开)。
请问有人有什么建议吗?
我不想使用
AppKit
,所以无论您建议什么解决方案,如果它仅在 SwiftUI 中创建,那就太好了。
这是我迄今为止尝试过的:
//
// MyApp.swift
// Power Schedule
//
// Created by Paul Randall on 10/07/2023.
//
// Importing necessary frameworks
// MyApp.swift
import SwiftUI
// MyApp.swift
class AppState: ObservableObject {
@Published var isMainWindowActive: Bool = false
}
@main
struct Power_ScheduleApp: App {
@State private var menuBarExtraShown = true
@State var isMainWindowOpen = false
var body: some Scene {
MenuBarExtra(isInserted: $menuBarExtraShown) {
AppMenu()
} label: {
Label("", image: "psl")
}
.menuBarExtraStyle(.menu)
WindowGroup {
ContentView()
.frame(width: 450, height: 948) // Set the desired width and height
.fixedSize()
.onAppear {
print("Main window appeared")
self.isMainWindowOpen = true
}
.onDisappear {
print("Main window disappeared")
self.isMainWindowOpen = false
}
}
.handlesExternalEvents(matching: ["main"])
.windowResizability(.contentSize)
.commands {
if isMainWindowOpen {
CommandGroup(replacing: .newItem) {
Button("New Window", action: {})
.disabled(true)
// This is the same keyboard shortcut as the default New Window option.
// We're just doing this so that our disabled dummy option shows
// the same shortcut visually.
.keyboardShortcut(KeyboardShortcut("n", modifiers: [.command]))
}
} else {
// By doing nothing here, we let the default
// "File -> New Window" item display and handle input.
EmptyCommands()
}
}
}
}
struct AppMenu: View {
@Environment(\.openURL) var openUrl
@Environment(\.dismiss) var dismiss
func launchAppMenu() {
// Launch the window from a URL
guard let url = URL(string: "launchps://main") else {return}
openUrl(url)
}
func importMenu() {
dismiss()
}
func quitAppMenu() {
// func 3 code
}
var body: some View {
Button(action: launchAppMenu, label: { Text("Launch My App") }).keyboardShortcut("n")
Button(action: importMenu, label: { Text("Import Configs") }).keyboardShortcut("i")
Divider()
Button(action: quitAppMenu, label: { Text("Quit My App") }).keyboardShortcut("q")
}
}
适用于 macOS 13+
使用
Window
代替 WindowGroup
在一个独特的窗口中呈现其内容的场景。
在您的代码中:
import SwiftUI
// MyApp.swift
@main
struct Power_ScheduleApp: App {
@State private var menuBarExtraShown = true
var body: some Scene {
MenuBarExtra(isInserted: $menuBarExtraShown) {
AppMenu()
} label: {
Label("", image: "psl")
}
.menuBarExtraStyle(.menu)
Window("Power Schedule", id: "main") { // <- open only one unique window
ContentView()
.frame(width: 450, height: 948) // Set the desired width and height
.fixedSize()
}
.handlesExternalEvents(matching: ["main"])
.windowResizability(.contentSize)
}
}