How to use @FocusedBinding

Viewed 1076

I've tried, without success, to use the new property wrapper @FocusedBinding.

The code example given here by a Frameworks Engineer, and placed below, during beta 1 period for iOS 14 and Big Sur compiles, but it doesn't seem to work for both OSs, for enabling the keyboard shortcuts.

Does anyone knows if something changed in the meantime, and how, or is something still under development?

// This example runs on macOS, iOS, and iPadOS.
//
// Big Sur Seed 1 has some known issues that prevent state-sharing between 
// windows and the main menu, so this example doesn't currently behave as 
// expected on macOS. Additionally, the Commands API is disabled on iOS in Seed 
// 1. These issues will be addressed in future seeds.
//
// The Focused Value API is available on all platforms. The Commands and
// Keyboard Shortcut APIs are available on macOS, iOS, iPadOS, and
// tvOS—everywhere keyboard input is accepted.
@main
struct MessageApp : App {
        var body: some Scene {
                WindowGroup {
                        MessageView()
                }
                .commands {
                        MessageCommands()
                }
        }
}
struct MessageCommands : Commands {
        // Try to observe a binding to the key window's `Message` model.
        //
        // In order for this to work, a view in the key window's focused view
        // hierarchy (often the root view) needs to publish a binding using the
        // `View.focusedValue(_:_:)` view modifier and the same `\.message` key
        // path (anologous to a key path for an `Environment` value, defined
        // below).
        @FocusedBinding(\.message) var message: Message?
        
        // FocusedBinding is a binding-specific convenience to provide direct
        // access to a wrapped value.
        //
        // `FocusedValue` is a more general form of the property wrapper, designed
        // to work with all value types, including bindings. The following is
        // functionally equivalent, but places the burden of unwrapping the bound
        // value on the client.
//      @FocusedValue(\.message) var message: Binding<Message>?
        
        var body: some Commands {
                CommandMenu("Message") {
                        Button("Send", action: { message?.send() })
                                .keyboardShortcut("D") // Shift-Command-D
                                .disabled(message?.text.isEmpty ?? true)
                }
        }
}
struct MessageView : View {
        @State var message = Message(text: "Hello, SwiftUI!")
        
        var body: some View {
                TextEditor(text: $message.text)
                        .focusedValue(\.message, $message)
                        .frame(idealWidth: 600, idealHeight: 400)
        }
}
struct Message {
        var text: String
        // ...
        
        mutating func send() {
                print("Sending message: \(text)")
                // ...
        }
}
struct FocusedMessageKey : FocusedValueKey {
        typealias Value = Binding<Message>
}
extension FocusedValues {
        var message: FocusedMessageKey.Value? {
                get { self[FocusedMessageKey.self] }
                set { self[FocusedMessageKey.self] = newValue }
        }
}
0 Answers
Related