Клавиатура iPhone исчезает и появляется снова при переключении между полями с помощью onTapGesture(hideKeyboard)

У меня есть этот код в 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
        )
    }
}

Спасибо.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Не следует помещать близкое действие клавиатуры на весь вид. Потому что он отключает клавиатуру, когда вы нажимаете где-нибудь. И причина его повторного появления заключается в том, что текстовое поле находится в режиме редактирования после закрытия клавиатуры.

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
        )
    }
}

Тоже работает, спасибо! При добавлении onTapGesture к цвету он охватывает большую часть областей. Если я хочу распространить это и на логотип изображения, то я могу просто добавить туда прослушиватель onTapGesture.

Petr Jelínek 04.07.2024 08:39
Ответ принят как подходящий

Еще одно решение похоже на

в вашем ZStack

ZStack {
       Color.yellow.frame(maxWidth: .infinity, maxHeight: .infinity).onTapGesture {
                        hideKeyboard()
                    }

И внизу нет необходимости нажимать на весь ваш ZStack.

ZStack {
//Your code
 }
        .ignoresSafeArea(.keyboard)
        .onTapGesture { self.hideKeyboard() }

            

Он должен работать.

Все работает отлично, большое спасибо!

Petr Jelínek 04.07.2024 08:38

Другие вопросы по теме