Maegan Wilson
Posted on April 29, 2022
Here’s how to make TextFields focused and not let a form close until the proper fields are filled out by the user.
This article is also a video
WWDC 2021 introduced the property wrapper @FocusState. It can be used to set which textfields are in focus pretty easily. I’m going to open this form for adding a new bag of coffee an app I’m working on.
Notice how when I click on save it just closes the form and doesn’t dismiss the keyboard. The @FocusState can help fix that. First thing that needs to be added is an enum with the fields that we want to be required.
private enum Field {
case name
case style
case roaster
}
The enum needs to conform to the Hashable protocol so you can either force conformance by adding : Hashable or as long as the cases don’t have a value assigned you should be good since Swift will do that “automagically”.
Now, we need to add a variable with the property wrapper @FocusState private var focusField: Field
Then on the TextFields, add the focused modifier and what field it should be equal to
TextField("Name", text: $beans.name)
.textFieldStyle(.roundedBorder)
.focused($focusedField, equals: .name)
TextField("Style", text: $beans.style)
.textFieldStyle(.roundedBorder)
.focused($focusedField, equals: .style)
TextField("Roaster", text: $beans.roaster)
.textFieldStyle(.roundedBorder)
.focused($focusedField, equals: .roaster)
Next, let’s put some logic in to make sure these fields are filled and set the next focusedField
Button {
if beans.name.isEmpty {
focusedField = .name
} else if beans.style.isEmpty {
focusedField = .style
} else if beans.roaster.isEmpty {
focusedField = .roaster
} else {
if isEdit {
beans.updateBean(context: viewContext)
} else {
beans.addBeansToData(context: viewContext)
resetBeans()
}
showForm = false
}
}
Also, after a successful save, we should set the focusedfield to nil and dismiss the keyboard
Button {
if beans.name.isEmpty {
focusedField = .name
} else if beans.style.isEmpty {
focusedField = .style
} else if beans.roaster.isEmpty {
focusedField = .roaster
} else {
if isEdit {
beans.updateBean(context: viewContext)
} else {
beans.addBeansToData(context: viewContext)
resetBeans()
}
showForm = false
focusedField = nil
}
}
Now, let’s run through the form one more time to just show it all together.
Hopefully that showed you how to use the @FocusState property wrapper. If you have any questions, then please drop a comment below.
Want my posts directly to your inbox?
Great! Sign up here!
Posted on April 29, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 19, 2024