Как использовать @FocusedBinding

#swiftui

#swiftui

Вопрос:

Я безуспешно пытался использовать новую оболочку свойств @FocusedBinding .

Пример кода, приведенный здесь инженером фреймворков и размещенный ниже, во время бета-версии 1 для iOS 14 и Big Sur компилируется, но, похоже, он не работает для обеих ОС, для включения сочетаний клавиш.

Кто-нибудь знает, изменилось ли что-то за это время и как, или что-то все еще находится в стадии разработки?

 // 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 }
        }
}
  

Комментарии:

1. Вы читали эту статью ? Он проделал хорошую работу, объяснив это.

2. Не было, но это не объясняет, как использовать его с сочетаниями клавиш. Приведенный пример работает, но в нем, если я попытался использовать @FocusedBinding для получения сообщения с изменениями из переменной внутри модификатора .commands в WindowGroup, это не сработает…

3. В том же потоке, ниже приведен обходной путь, добавьте @FocussedBinding в представление, содержащее кнопку. См. — developer.apple.com/forums/thread /…

4. Обходной путь работает для macOS. Однако для iOS (по крайней мере, в 15) команды MessageCommands Commands могут быть прочитаны и «активированы», но @FocusedBinding и @FocusedValues не могут быть прочитаны из них, даже если они находятся внутри представления.

5. Да, вы правы, я только что понял это, когда мне было интересно, почему это не работает на симуляторе iPad. Надеюсь, это будет исправлено