init<T>()
init()
Availability 有効性
Technology
@frozen @propertyWrapper struct FocusState<Value> where Value : Hashable
Use this property wrapper in conjunction with focused(_:
and focused(_:)
to describe views whose appearance and contents relate to the location of focus in the scene. When focus enters the modified view, the wrapped value of this property updates to match a given prototype value. Similarly, when focus leaves, the wrapped value of this property resets to nil
or false
. Setting the property’s value programmatically has the reverse effect, causing focus to move to the view associated with the updated value.
In the following example of a simple login screen, when the user presses the Sign In button and one of the fields is still empty, focus moves to that field. Otherwise, the sign-in process proceeds.
struct LoginForm {
enum Field: Hashable {
case username
case password
}
private var username = ""
private var password = ""
private var focusedField: Field?
var body: some View {
Form {
TextField("Username", text: $username)
.focused($focusedField, equals: .username)
SecureField("Password", text: $password)
.focused($focusedField, equals: .password)
Button("Sign In") {
if username.isEmpty {
focusedField = .username
} else if password.isEmpty {
focusedField = .password
} else {
handleLogin(username, password)
}
}
}
}
}
To allow for cases where focus is completely absent from a view tree, the wrapped value must be either an optional or a Boolean. Set the focus binding to false
or nil
as appropriate to remove focus from all bound fields. You can also use this to remove focus from a Text
and thereby dismiss the keyboard.
The same view can have multiple focus bindings. In the following example, setting focused
to either name
or full
causes the field to receive focus:
struct ContentView: View {
enum Field: Hashable {
case name
case fullName
}
private var focusedField: Field?
var body: some View {
TextField("Full Name", ...)
.focused($focusedField, equals: .name)
.focused($focusedField, equals: .fullName)
}
}
On the other hand, binding the same value to two views is ambiguous. In the following example, two separate fields bind focus to the name
value:
struct ContentView: View {
enum Field: Hashable {
case name
case fullName
}
private var focusedField: Field?
var body: some View {
TextField("Name", ...)
.focused($focusedField, equals: .name)
TextField("Full Name", ...)
.focused($focusedField, equals: .name) // incorrect re-use of .name
}
}
If the user moves focus to either field, the focused
binding updates to name
. However, if the app programmatically sets the value to name
, SwiftUI chooses the first candidate, which in this case is the “Name” field. SwiftUI also emits a runtime warning in this case, since the repeated binding is likely a programmer error.
var projectedValue : FocusState <Value>.Binding
struct Binding
var wrappedValue : Value
struct FocusedBinding
struct FocusedValue
struct FocusedValues
protocol FocusedValueKey