在基于文档的 macOS 应用程序启动时显示一个窗口

问题描述 投票:0回答:1

我有一个基于文档的 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 来实现这一点。将把这个问题留在这里,以防有更好的方法可用。

macos swiftui
1个回答
0
投票

macOS 15.0+

添加了新的

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 中重新运行应用程序,则启动时不会出现该窗口。

macOS <15.0

您应该能够为此使用

.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")
                    }
            }
        }
    }
}

注意:这可能不适用于仅实用程序的应用程序,因为我不确定命令是否已初始化,但我还没有尝试过。

© www.soinside.com 2019 - 2024. All rights reserved.