我有一个基于文档的 SwiftUI 应用程序,我正在尝试在启动时显示一个欢迎窗口(如 Xcode 中的窗口)。
我有:
Window("Welcome", id: "welcome") {
WelcomeView()
}
.windowStyle(.hiddenTitleBar)
.windowResizability(.contentSize)
这看起来不错,并且出现在“窗口”菜单中的适当位置(而不是在文档窗口中)。问题是我不知道如何让它在启动时显示。我尝试过的事情:
@Environment(\.openWindow) var openWindow
并在 openWindow
init 函数中调用 App
。这会导致需要从 SwiftUI 生命周期内调用 openWindow
的错误(这是有道理的,因为 body
甚至尚未被调用)。openWindow
中并休眠一会儿来延迟对 Task
的呼叫。什么也没发生。@Environment(\.scenePhase)
触发对 openWindow
的呼叫。仅在创建文档窗口后才会发生这种情况(为时已晚)。WindowGroup
代替 Window
和 handlesExternalEvents
。 WindowGroup
似乎不是正确的使用方式:文件 -> 新建成为包含我的普通文档和欢迎窗口的子菜单。View
,因此无法使用onAppear
。我很可能可以通过下拉到 AppKit、使用 AppDelegate、显式创建一个 NSWindow 并在其中托管
WelcomeView
来实现此目的。但我真的不应该这样做。有没有办法在纯 SwiftUI 中做到这一点?
更新:我确实通过下拉到 AppKit 来实现这一点。将把这个问题留在这里,以防有更好的方法可用。
defaultLaunchBehavior(_:)
修改器,允许您设置场景的启动行为。在这种情况下,我们要使用 .presented
。
在上面链接的文档中,他们甚至显示了一个带有欢迎窗口的示例:
@main
struct MyApp: App {
var body: some Scene {
DocumentGroup(newDocument: MyDocument()) { configuration in
DocumentEditor(configuration.$document)
}
Window("Welcome to My App", id: "welcome") {
WelcomeView()
}
.defaultLaunchBehavior(.presented)
}
}
⚠️ 但是,从我在 macOS 15.0 beta 3 上的测试来看,这似乎还不起作用。如果我关闭应用程序的窗口 (CMD+W),然后在 Xcode 中重新运行应用程序,则启动时不会出现该窗口。
您应该能够为此使用
.commands
修饰符,因为命令始终在启动时初始化,即使不存在窗口也是如此。
这里我使用
Color.clear
添加一个空命令,使其在实际命令菜单中不可见。如果您已经设置了自定义命令,则只需在其中添加 .onAppear
即可。
import SwiftUI
@main
struct YourApp: App {
@Environment(\.openWindow) private var openWindow
var body: some Scene {
Window("Welcome", id: "welcome") {
WelcomeView()
}
// NEW
.commands {
CommandGroup(after: .appInfo) {
Color.clear
.onAppear {
openWindow(id: "welcome")
}
}
}
}
}
注意:这可能不适用于仅实用程序的应用程序,因为我不确定命令是否已初始化,但我还没有尝试过。