Reputation: 1
is there a possible way when we are in the textfield then pressing tab button the picker is automatically selected, by using @FocusState?
i have tried using @FocusState but it seems it only works on textFields, is there other way that it will work on pickers?
struct FormFields: View {
@FocusState private var focusedField: Field?
@ObservedObject var viewModel: AddCustomerViewModel
@Binding var showReference: Bool
enum Field: Hashable {
case name, classification
}
var body: some View {
VStack {
TextField(Labels.name, text: $viewModel.name)
.focused($focusedField, equals: .name)
.onSubmit { focusedField = .classification }
Picker(Labels.classification, selection: $viewModel.classification) {
Text("").tag(nil as CustomerClassification?)
ForEach(CustomerClassification.allCases, id: \.self) { classification in
Text(classification.rawValue).tag(classification as CustomerClassification?)
}
}
.focused($focusedField, equals: .classification)
}
}
Upvotes: 0
Views: 57
Reputation: 31647
To implement the behavior where pressing the Tab
key focuses on a Picker
when the TextField
is focused (and vice versa), you're on the right track with using @FocusState
. But there is a subtle issue, the Picker
doesn't automatically take focus in the same way a TextField
does.
The challenge is that @FocusState
works directly with views that can take focus, such as TextField
and TextEditor
. For other views like Picker
, focus management isn't built-in, but you can still work around this limitation by adjusting the logic around when the Picker
should be treated as focused.
To achieve this, we need to use the .onChange
modifier to detect when the focusedField
changes, and then trigger selection on the Picker
.
struct FormFields: View {
@FocusState private var focusedField: Field?
@ObservedObject var viewModel: AddCustomerViewModel
@Binding var showReference: Bool
enum Field: Hashable {
case name, classification
}
var body: some View {
VStack {
TextField(Labels.name, text: $viewModel.name)
.focused($focusedField, equals: .name)
.onSubmit {
focusedField = .classification // Move to the next field
}
Picker(Labels.classification, selection: $viewModel.classification) {
Text("").tag(nil as CustomerClassification?)
ForEach(CustomerClassification.allCases, id: \.self) { classification in
Text(classification.rawValue).tag(classification as CustomerClassification?)
}
}
.focused($focusedField, equals: .classification)
.onChange(of: focusedField) { newValue in
if newValue == .classification {
// You can add logic here to trigger a default picker selection if necessary
// For example, if you want to select a default classification:
if viewModel.classification == nil {
viewModel.classification = CustomerClassification.allCases.first
}
}
}
}
.onChange(of: focusedField) { newFocus in
// Handle the change in focus (e.g., when Tab is pressed)
if newFocus == .name {
// Logic when the focus is on the name field
}
if newFocus == .classification {
// Logic when the focus is on the classification Picker
}
}
}
}
Upvotes: 0