У меня есть этот код в Swift (iOS 16+), и у меня есть экран входа в мое приложение, где пользователю необходимо ввести адрес электронной почты и пароль.
У меня также есть метод .onTapGesture
, позволяющий GeometryReader { ... }
свернуть все воедино. Я хочу, чтобы пользователь мог отключить клавиатуру, нажав на текстовое поле.
Но когда пользователь вводит адрес электронной почты, а затем хочет ввести пароль, клавиатура исчезает, а затем появляется снова. Как я могу это сделать, чтобы клавиатура оставалась открытой (тот же ожидаемый результат, что и без onTapGesture).
Вот мой код
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
)
}
}
Спасибо.
Не следует помещать близкое действие клавиатуры на весь вид. Потому что он отключает клавиатуру, когда вы нажимаете где-нибудь. И причина его повторного появления заключается в том, что текстовое поле находится в режиме редактирования после закрытия клавиатуры.
struct MyView: 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)
.onTapGesture { self.hideKeyboard() }
VStack {
WelcomeTextView(welcomeText: "sign_in_to")
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.top, screenHeight * 0.02)
.onTapGesture { self.hideKeyboard() }
VStack {
InputField(
text: $email,
placeholder: "enter_email",
isSecure: false
)
.padding(.bottom, 15)
InputField(
text: $password,
placeholder: "enter_password",
isSecure: true,
trailingIcon: Image("Lock")
)
}
Group {
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)
}
.onTapGesture { self.hideKeyboard() }
Spacer()
}
.paddedFrame(
screenSize: screenGeometry.size,
horizontalSizeClass: horizontalSizeClass
)
}
}
.ignoresSafeArea(.keyboard)
}
private func hideKeyboard() {
// UIApplication.shared.keyWindow?.endEditing(true) - Depricated
UIApplication.shared.sendAction(
#selector(UIResponder.resignFirstResponder),
to: nil,
from: nil,
for: nil
)
}
}
Еще одно решение похоже на
в вашем ZStack
ZStack {
Color.yellow.frame(maxWidth: .infinity, maxHeight: .infinity).onTapGesture {
hideKeyboard()
}
И внизу нет необходимости нажимать на весь ваш ZStack.
ZStack {
//Your code
}
.ignoresSafeArea(.keyboard)
.onTapGesture { self.hideKeyboard() }
Он должен работать.
Все работает отлично, большое спасибо!
Тоже работает, спасибо! При добавлении onTapGesture к цвету он охватывает большую часть областей. Если я хочу распространить это и на логотип изображения, то я могу просто добавить туда прослушиватель onTapGesture.