在 SwiftUI AppLifecycle 文档应用程序中,如何在活动的 ContentView 中获取菜单命令?

问题描述

我正在使用 SwiftUI 应用程序生命周期编写一个 MacOS 文档应用程序,我在这里和其他地方看到的用于将菜单操作发送到活动窗口的所有技巧都依赖于使用特定于平台的实现,这(大部分)在SwiftUI 生命周期应用程序。我正在寻找的是 SideBarCommands() 之类的东西,它添加一个菜单项,当通过鼠标或命令键选择时,它会在活动窗口中切换侧边栏的外观。到目前为止,我所看到的所有命令示例都是微不足道的,没有一个解决多文档、多窗口用例。

鉴于这样声明的 ContentView:

struct ContentView: View {
    @Binding var document: TickleDocument

    var body: some View {
        TextEditor(text: $document.text)
    }
    
    public func menuTickle() {
        document.text = "Wahoo!"
    }
}

一个命令,通过以下方式添加

struct TickleApp: App {
    public static var target:TickleDocument?
    
    var body: some Scene {
        let docgroup = DocumentGroup(newDocument: TickleDocument()) { file in
            ContentView(document: file.$document)
        }
        
        docgroup
            .commands {
                CommandMenu("App Tickles") {
                    Button("Tickle The ContentView") {
                      // Here's where I need to call menuTickle() on the active ContentView
                    }.keyboardShortcut("t")
                }
            }
        }
    }
}

我需要做什么才能让按钮闭包调用 active ContentView 上的 menuTickle()?我知道它可以做到,因为 SideBarCommands() 做到了(除非 Apple 使用一些非公共 API 来做到这一点......)。

对于奖励积分,请告诉我如何在评估 body 时检测我是否是活动的 ContentView,以及如何检测它何时发生变化!跟踪 Environment 变量 scenePhase 毫无价值 - 它始终报告活动状态,从不更改。

解决方法

我的问题与 this one 重复。

该问题的答案包含指向我已验证有效的解决方案的链接,可以在 here