How it works
FocusedValues is a key-indexed container that holds values published by the view hierarchy currently in focus, much as the environment holds values for the whole hierarchy. It lets a view far from the focused one — a toolbar button, a menu command, an inspector — read state that belongs to whatever the user is actively working in, without threading that state through bindings or shared model objects. Reach for it when an action's meaning depends on the focused view: the same Delete command, Rename field, or detail panel that must operate on the current selection rather than a fixed target.
Declare a key by conforming to FocusedValueKey
Every focused value is addressed by a type that conforms to
FocusedValueKeyand declares the associatedValueit carries. HereSelectedNoteKeyis a nested type whosetypealias Value = Stringsays this key publishes a note string. The key type itself is never instantiated; it serves purely as the compile-time identity that links a producer and a consumer.Publish a value with focusedValue(_:_:)
A focusable view writes into the focused-values store by attaching
.focusedValue(SelectedNoteKey.self, note). Whenever that view holds focus, SwiftUI recordsnoteunderSelectedNoteKeyin the active FocusedValues; when focus moves elsewhere, the entry is withdrawn. The modifier hangs on theTextField, the element that actually receives focus.Read the value with the @FocusedValue property wrapper
A consumer observes the store by declaring
@FocusedValue(SelectedNoteKey.self) private var focusedNote. The wrapper resolves to the value most recently published for that key by the focused part of the hierarchy, and re-renders the view when focus or the published value changes. Because focus can be absent, the projected value is optional —focusedNoteis aString?.Handle the unfocused case
FocusedValues returns no entry when nothing in focus publishes the key, so reads are nil-safe by design. The example coalesces that absence in
focusedNote ?? "none", which displaysnoneuntil theTextFieldgains focus and begins supplyingnotethroughSelectedNoteKey.
TextField bound to its own @State and give it .focusedValue(SelectedNoteKey.self, ...) with a different string, then click between the two fields to watch focusedNote track whichever one currently holds focus.Example & preview
Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.
struct FocusedValuesDemo: View {
struct SelectedNoteKey: FocusedValueKey {
typealias Value = String
}
@State private var note = "Grocery list"
@FocusedValue(SelectedNoteKey.self) private var focusedNote
var body: some View {
VStack(alignment: .leading, spacing: 12) {
TextField("Note", text: $note)
.textFieldStyle(.roundedBorder)
.focusedValue(SelectedNoteKey.self, note)
Text("Focused note: \(focusedNote ?? "none")")
.font(.callout)
.foregroundStyle(.secondary)
}
.padding()
}
}