Focus State in SwiftUI
Managing focus state in SwiftUI is essential for creating accessible and user-friendly forms and interactive interfaces. The @FocusState property wrapper allows you to programmatically control which field has focus, improving keyboard navigation and user experience.
What is @FocusState?
@FocusState is a property wrapper introduced in iOS 15 that enables you to track and control which view has keyboard focus. This is particularly useful for forms, text fields, and creating accessible user interfaces where keyboard navigation is important.
Basic Usage for a search view
Here's an example of using @FocusState in a search view:
import SwiftUI
struct SearchView: View {
@State private var searchText = ""
@FocusState private var isSearchFieldFocused: Bool
var body: some View {
VStack {
TextField("Search...", text: $searchText)
.focused($isSearchFieldFocused)
}
.padding()
.task {
isSearchFieldFocused = true // Automatically focus the search field when the view appears
}
}
}
Basic Usage (User Login Form)
Here's a simple example of using @FocusState with a text field:
import SwiftUI
struct LoginView: View {
@State private var username = ""
@State private var password = ""
@FocusState private var focusedField: Field?
enum Field {
case username
case password
}
var body: some View {
Form {
TextField("Username", text: $username)
.focused($focusedField, equals: .username)
SecureField("Password", text: $password)
.focused($focusedField, equals: .password)
Button("Login") {
focusedField = nil // Dismiss keyboard
}
}
.onAppear {
focusedField = .username
}
}
}
Use Case: Form Validation (Sign-Up Form)
You can use @FocusState to automatically move focus to the next field after validation or to highlight invalid fields:
struct SignUpForm: View {
@State private var email = ""
@State private var password = ""
@State private var confirmPassword = ""
@FocusState private var focusedField: Field?
enum Field: Hashable {
case email, password, confirmPassword
}
var body: some View {
Form {
TextField("Email", text: $email)
.focused($focusedField, equals: .email)
.onSubmit {
focusedField = .password
}
SecureField("Password", text: $password)
.focused($focusedField, equals: .password)
.onSubmit {
focusedField = .confirmPassword
}
SecureField("Confirm Password", text: $confirmPassword)
.focused($focusedField, equals: .confirmPassword)
.onSubmit {
submitForm()
}
}
}
func submitForm() {
guard !email.isEmpty else {
focusedField = .email
return
}
guard password == confirmPassword else {
focusedField = .confirmPassword
return
}
focusedField = nil
}
}
Accessibility Benefits
Using @FocusState improves accessibility by:
-
Enabling better keyboard navigation
-
Supporting assistive technologies
-
Providing clear focus indicators
-
Allowing programmatic focus control for better UX
Wrap up
@FocusState is a powerful tool for managing keyboard focus in SwiftUI applications. It enhances both the user experience and accessibility of your forms and interactive views by providing fine-grained control over focus management.
Resources:
Read more
- @dynamicMemberLookup • 2 minutes reading time.
- Keyboard Navigation • 11 minutes reading time.
- Thermal States on iOS • 3 minutes reading time.
Share
Share Bluesky Mastodon Twitter LinkedIn Facebook