Reputation: 1904
I am using the new MultiPlatform SwiftUI Document template in Xcode 12 and I don't understand how to get access to the current FileDocument from within a menu item.
My app code looks like this (straight from the template).
@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")
}
}
}
}
}
Upvotes: 4
Views: 1992
Reputation: 66
You can create a FocusedValueKey
, publish a binding to the document from your content view, and then observe it in the menu using @FocusedBinding
. There is a great explanation here.
Upvotes: 5
Reputation: 1904
To answer my own question, this is how I solved it. You can just send a signal from the .commands section via Combine.
@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...")
}
}
}
}
}
Upvotes: -1
Reputation: 258365
Here is a demo of possible approach. The idea is to use app state object to store current document in it and access from any place needed.
Tested with 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?
}
Upvotes: -1