In SwiftUI 3 @FocusState
wrapper can be used to remove or switch focus from editable fields. When the focus is removed from field, keyboard dismisses. So in your case it is just a matter of giving space and gesture to the surrounding space of TextView
.
struct ContentView: View {
@State var inputValue : String = ""
@FocusState private var inputIsFocused: Bool
var body: some View {
VStack(spacing: 10) {
TextField("$", text: $inputValue)
.keyboardType(.decimalPad)
.border(Color.green)
.focused($inputIsFocused)
}
.frame(maxHeight: .infinity) // If input is supposed to be in the center
.background(.yellow)
.onTapGesture {
inputIsFocused = false
}
}
}
But we can do more interesting things with @FocusState
. How about switching from field to field in a form. And if you tap away, keyboard also dismisses.
struct ContentView: View {
enum Field {
case firstName
case lastName
case emailAddress
}
@State private var firstName = ""
@State private var lastName = ""
@State private var emailAddress = ""
@FocusState private var focusedField: Field?
var body: some View {
ZStack {
VStack {
TextField("Enter first name", text: $firstName)
.focused($focusedField, equals: .firstName)
.textContentType(.givenName)
.submitLabel(.next)
TextField("Enter last name", text: $lastName)
.focused($focusedField, equals: .lastName)
.textContentType(.familyName)
.submitLabel(.next)
TextField("Enter email address", text: $emailAddress)
.focused($focusedField, equals: .emailAddress)
.textContentType(.emailAddress)
.submitLabel(.join)
}
.onSubmit {
switch focusedField {
case .firstName:
focusedField = .lastName
case .lastName:
focusedField = .emailAddress
default:
print("Creating account…")
}
}
}
.textFieldStyle(.roundedBorder)
.padding()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.contentShape(Rectangle()) // So ZStack becomes clickable
.onTapGesture {
focusedField = nil
}
}
}