Monitoring key window in SwiftUI on a Mac, part 2
I had difficulties making menu bar commands respond to a user interface state when an app running in multiple windows or tabs. In short, I have used .controlActiveState
environment with some workarounds. More details in the previous post. The workaround is not useful when I tested my application with multiple window tabs running. I even had to disable the window tabs altogether. I am happy to share that I found a solution which works with windows and tabs.
You might think that there’s a new beta API introduced with macOS 14.6. Actually, it took me some time to figure out and implement a solution which works on macOS 14.5 and even on 14.4.
The solution which I found in the Hacking With Swift blog post works with adding an ObservableObject
class and using .focusedSceneObject
SwiftUI view modifier.
Defining state:
final class EditorState: ObservableObject {
@Published var editorMode: EditorMode = .editor
}
Magic SwiftUI glue.
.focusedSceneObject(editorState)
Accessing state:
@FocusedObject var editorState: EditorState?
Helpful links
- Doc-App global state with focusedSceneObject solves MacOS dynamic Menu issues
- Provide the current document to menu commands in a SwiftUI app
- FocusedValue and FocusedBinding property wrappers in SwiftUI
- How to use @FocusState with view models?
- Mastering FocusState property wrapper in SwiftUI
- Craig Hockenberry’s question about custom views and focus state.
- Window management in SwiftUI
Real application
This post wouldn’t be possible without the work which went into LinkEdit. It describes one of the many features and improvements included in recent 1.3 major update.