I have this code in Swift (iOS 16+) and I have a login screen into my app, where the user needs to enter an email and password.
I also have a .onTapGesture
method on the GeometryReader { ... }
wrapping everything together. I want the user to be able to dismiss the keyboard when tapping away from the text field.
But when the user enters an email and then wants to enter a password, the keyboard disappear and then appears again. How can I do that so the keyboard stays open (same expecting result as without the onTapGesture).
Here is my code
struct LoginView: View {
@Environment(.horizontalSizeClass) var horizontalSizeClass
@State var email: String = ""
@State var password: String = ""
private let hapticFeedbackService = HapticFeedbackService()
var body: some View {
GeometryReader { screenGeometry in
let screenHeight = screenGeometry.size.height
ZStack {
Color.black.background.ignoresSafeArea(.all)
VStack {
WelcomeTextView(welcomeText: "sign_in_to")
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.top, screenHeight * 0.02)
VStack {
InputField(
text: $email,
placeholder: "enter_email",
isSecure: false
)
.padding(.bottom, 15)
InputField(
text: $password,
placeholder: "enter_password",
isSecure: true,
trailingIcon: Image("Lock")
)
}
Button(action: {
hapticFeedbackService.triggerHapticFeedback()
print("Button pressed")
}) {
Text(LocalizedStringKey("forgot_your_password"))
.font(.thinnerSmallTitle)
}
.padding(.top, 5)
.padding(.trailing, 5)
.frame(maxWidth: .infinity, alignment: .trailing)
LargeButton(
text: "sign_in",
textColor: Color.black,
backgroundColor: Color.white
) {
hapticFeedbackService.triggerHapticFeedback()
print("Button pressed")
}
.padding(.top, 40)
Text(LocalizedStringKey("other_login_options"))
.font(.mediumText)
.padding(.top, 10)
HStack {
SSOButton(type: .Apple, action: {
hapticFeedbackService.triggerHapticFeedback()
print("Button pressed")
})
.padding(.trailing, 5)
SSOButton(type: .Google, action: {
hapticFeedbackService.triggerHapticFeedback()
print("Button pressed")
})
.padding(.leading, 5)
}
.padding(.top, 10)
HStack {
Text(LocalizedStringKey("dont_have_account"))
.font(.mediumText)
.foregroundColor(Color.black)
Button(action: {
hapticFeedbackService.triggerHapticFeedback()
print("Button pressed")
}) {
Text(LocalizedStringKey("dont_have_account_sign_up"))
.font(.smallTitle)
.foregroundColor(Color.black)
}
}
.padding(.top, 25)
Spacer()
}
.paddedFrame(
screenSize: screenGeometry.size,
horizontalSizeClass: horizontalSizeClass
)
}
}
.ignoresSafeArea(.keyboard)
.onTapGesture { self.hideKeyboard() }
}
private func hideKeyboard() {
// UIApplication.shared.keyWindow?.endEditing(true) - Depricated
UIApplication.shared.sendAction(
#selector(UIResponder.resignFirstResponder),
to: nil,
from: nil,
for: nil
)
}
}
Thank you.
2
Answers
You shouldn’t put close keyboard action to the whole view. Beause it will dismiss the keyboard when you click anywhere. And the reason its reappearing is textfield realizing its on edit mode after the keyboard dismisses.
To help you better, could you please provide specific issue you are facing with your Swift code? Are you encountering any other errors, or do you need only assistance with a particular aspect of the login screen implementation, like form validation, networking, or user interface design? Let me know so I can provide you with the most relevant assistance.