基于文档的应用程序,如何在菜单中访问文档?

4

我正在使用Xcode 12中的新MultiPlatform SwiftUI Document模板,但我不知道如何从菜单项中访问当前的FileDocument。

我的应用代码看起来像这样(直接从模板复制)。

@main
struct MyApp: App {
    var body: some Scene {
        DocumentGroup(newDocument: MyDocument()) { file in
            ContentView(document: file.$document)
        }
        .commands {
            CommandMenu("Utilities") {
                Button(action: {
                    // How to get access to the current FileDocument ?
                }) {
                    Text("Test")
                }
            }
        }
    }
}
3个回答

5

您可以创建一个FocusedValueKey,从您的内容视图发布绑定到文档,然后使用@FocusedBinding在菜单中观察它。这里有一个很好的解释


链接是404。 - Chris
谢谢Chris,我已经更新了链接。 - Gareth Redman

-1
回答自己的问题,这是我解决它的方法。您可以通过Combine从.commands部分发送信号。
@main
struct MyApp: App {

    private let exportAsImage = PassthroughSubject<Void, Never>()

    var body: some Scene {
        DocumentGroup(newDocument: MyDocument()) { file in
            ContentView(document: file.$document)
                .onReceive(exportAsImage) { _ in
                    file.document.exportAsImage()
                }
        }
        .commands {
            CommandGroup(replacing: .importExport) {
                Button(action: {
                    exportAsImage.send()
                }) {
                    Text("Export as Image...")
                }
            }
        }
    }
}

1
当您拥有多个文档并单击按钮时,所有文档都会开始导出吗? - fuermosi777
不,该事件仅发送到当前文档。 - Markus Moenig
我尝试过,事件接收到了所有打开的选项卡。 - Viktor Goltvyanitsa

-1
这是一个可能的方法演示。思路是使用应用程序状态对象将当前文档存储在其中,并从任何需要的地方访问。
已在Xcode 12 / iOS 14上进行了测试。
@main
struct MyApp: App {
    @StateObject var appState = AppState()

    var body: some Scene {
        DocumentGroup(newDocument: MyDocument()) { file in
            createView(for: file)
        }
        .commands {
            CommandMenu("Utilities") {
                Button(action: {
                    if let doc = appState.currentDocument {
                        // do something
                    }
                }) {
                    Text("Test")
                }
            }
        }
    }

    private func createView(for file: FileDocumentConfiguration<MyDocument>) -> some View {
        appState.currentDocument = file.document
        return ContentView(document: file.document)
    }
}

class AppState: ObservableObject {
    @Published var currentDocument: MyDocument?
}

2
谢谢您的回复,但是在OS X下似乎没有调用createView()。另外,由于可以在视图之间切换,createView()是否只会存储最后创建的视图而不是当前选定的视图? - Markus Moenig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接