In reference to this article ( https://nilcoalescing.com/blog/ProvidingTheCurrentDocumentToMenuCommands/ ), you can do it with @FocusedBinding. I don't even know what this @FocusedBinding guy is. It's been around since macOS 11? Ugh...
import SwiftUI
@main
struct FocusedBindingCrazyMamaApp: App {
var body: some Scene {
DocumentGroup(newDocument: FocusedBindingCrazyMamaDocument()) { file in
ContentView(document: file.$document)
.focusedSceneValue(\.focusedDocument, file.$document)
}
.commands {
CommandGroup(replacing: .saveItem) {
UppercasedText()
LowercasedText()
}
}
}
}
extension FocusedValues {
struct DocumentFocusedValues: FocusedValueKey {
typealias Value = Binding<FocusedBindingCrazyMamaDocument>
}
var focusedDocument: Binding<FocusedBindingCrazyMamaDocument>? {
get {
self[DocumentFocusedValues.self]
}
set {
self[DocumentFocusedValues.self] = newValue
}
}
}
struct UppercasedText: View {
@FocusedBinding(\.focusedDocument) var focusedDocument
var body: some View {
Button {
guard let text = focusedDocument?.text else {
return
}
focusedDocument?.text = text.uppercased()
} label: {
Text("Uppercase Text")
}
.disabled(focusedDocument == nil)
.keyboardShortcut("u", modifiers: [.command, .shift])
}
}
struct LowercasedText: View {
@FocusedBinding(\.focusedDocument) var focusedDocument
var body: some View {
Button {
guard let text = focusedDocument?.text else {
return
}
focusedDocument?.text = text.lowercased()
} label: {
Text("Lowercase Text")
}
.disabled(
focusedDocument == nil
)
.keyboardShortcut("l", modifiers: [.command, .shift])
}
}
// ContentView.swift //
import SwiftUI
struct ContentView: View {
@Binding var document: FocusedBindingCrazyMamaDocument
var body: some View {
TextEditor(text: $document.text)
.foregroundStyle(.white)
.font(.system(size: 24))
.scrollContentBackground(.hidden)
.background(.black)
}
}
#Preview {
ContentView(document: .constant(FocusedBindingCrazyMamaDocument()))
}