Post

Replies

Boosts

Views

Activity

Using @FocusedBinding with a Class to update a CommandMenu
This is for MacOS. I am trying to send a message to a Model Object using a CommandMenu and then change the menu button title in response, with only partial success. I am using @FocusedBinding and .focusedValue so that the model can be created in my view rather than at the App level. I want to do this so that I can switch to a document style app and have different model instances. In the following example everything works as it should IF the model is a Struct. However I REQUIRE that the model be a Class so I can observe changes. If the model is switched to a class by commenting out the struct Model and uncommenting the class Model in the example below there are two problems that I can't seem to fix: First, the menu never switches from ‘Play’ to ‘Stop’ Second, I can’t change the Model var annotation to @StateObject - which is what a class really needs - without getting an error on the .focusedValue modifier. Any help sorting this out would be greatly appreciated import SwiftUI @main struct MessageApp : App {     var body: some Scene {         WindowGroup {             MessageView()         }         .commands {             AppCommands()         }     } } struct AppCommands : Commands { struct PlayMenu : View {         @FocusedBinding(\.model) var model: Model?         var body: some View {             Button((model?.playing ?? false) ? "Stop" : "Play", action: { model?.send(command: .play) }).keyboardShortcut(.space, modifiers: [])         }     }     var body: some Commands {         CommandMenu("Play") {             PlayMenu()         }     } } struct MessageView : View {     @State private var model = Model()     var body: some View {         Rectangle()             .focusedValue(\.model, $model)             .frame(idealWidth: 600, idealHeight: 400)     } } //class Model : ObservableObject{ //    @Published var playing: Bool = false // //    func send(command: ModelCommands) { //        playing.toggle() //        print(playing) //    } //} struct Model{     var playing: Bool = false     mutating func send(command: ModelCommands) {         playing.toggle()         print(playing)     } } struct FocusedModelBinding: FocusedValueKey {     typealias Value = Binding<Model> } extension FocusedValues {     var model: FocusedModelBinding.Value? {         get { self[FocusedModelBinding.self] }         set { self[FocusedModelBinding.self] = newValue }     } } enum ModelCommands: CaseIterable{     case play }
1
0
755
Jan ’22