So I took the demo code and added a little bit of debug as shown below.
As far as I can tell, there are two problems.
First that focusedValue on ContentView was not being set because the View is not being focused. Which can be seen because the @FocusBinding in OtherView doesn't pick up the price value as expected.
This could be a SwiftUI bug, but it's easy to work around by switching over to the focusedSceneValue modifier. Anyway, with that in place the price in ContentView and OtherView keeps in step.
The second problem is that even with the first fix/workaround in place, changes in the price are never causing the Custom menu to be rebuilt after it's initial rendering.
I think this is a bug with SwiftUI and would recommend submitting a feedback submission to Apple letting them know about it.
The workaround (in this case) with price being app global state, would be to just pass it through to PriceCommands as an argument (as is already being done for ContentView).
Kind regards
import SwiftUI
@main
struct TestApp: App {
@State private var price = 0
var body: some Scene {
WindowGroup {
ContentView(price: $price)
.focusedSceneValue(\.price, $price) // <== Changed
}
.commands {
PriceCommands()
}
}
}
struct OtherView: View {
@FocusedBinding(\.price) var price: Int?
var body: some View {
Text("OtherView price = \(String(describing: price))")
}
}
struct ContentView: View {
@Binding var price: Int
var body: some View {
VStack {
OtherView()
IncreasePriceButton(price: $price)
}
}
}
struct IncreasePriceButton: View {
@Binding var price: Int
var body: some View {
Button("Increase Price") {
price += 1
print("price = \(price)")
}
}
}
struct PriceCommandButton: View {
@FocusedBinding(\.price) var price
var priceText: String {
String(price ?? -1)
}
var body: some View {
print("Buiding commands menu with \(String(describing: price))")
return Button("Print Price \(priceText)") {
print("price = \(String(describing: price))")
}
}
}
struct PriceCommands: Commands {
var body: some Commands {
CommandMenu("Custom") {
PriceCommandButton()
.keyboardShortcut(KeyboardShortcut("C", modifiers: [.command, .shift]))
}
}
}
struct FocusedPriceKey: FocusedValueKey {
typealias Value = Binding<Int>
}
extension FocusedValues {
var price: FocusedPriceKey.Value? {
get { self[FocusedPriceKey.self] }
set { self[FocusedPriceKey.self] = newValue }
}
}