Home > Software engineering >  SwiftUI - FocusState opens keyboard on view state change
SwiftUI - FocusState opens keyboard on view state change

Time:09-02

I have a view with Textfields and I am using FocusStates.

My problem is that when I want to show an error message, the Keyboard is showing up. How can I hide the keyboard when the view is reloading?

struct SignInUI: View {
    @State var email: String = ""
    @State var password: String = ""
    private enum Field: Int, CaseIterable {
        case username, password
    }
    @FocusState private var focusedField: Field?
    @StateObject var viewModel: SignInViewModel
    
    var body: some View {
        Group {
            switch viewModel.state {
            case .loading:
                ZStack {
                    content
                    ProgressView()
                }
                
            case .error:
                ZStack {
                    content
                    ErrorView()
                }
                
            case .loaded:
                content
            }
        }
    }
    
    var content: some View {
        VStack {
            PasswordTextField(field: $password)
                .focused($focusedField, equals: .password)
            EmailTextField(field: $email)
                .focused($focusedField, equals: .username)
            
            ButtonView(text: "Sign In", action: {
                focusedField = nil
                viewModel.signIn(email: email, password: password)
            })
        }
    }
}

CodePudding user response:

Try setting focusedField to nil when the ErrorView appears:

case .error:
    ZStack {
        content
        ErrorView()
            .onAppear {
                focusedField = nil
            }
    }

CodePudding user response:

I find this to be the most versatile way to disable keyboard. You can add a state to detect isReloading state, and call this function to disable keyboard.

import SwiftUI

struct HideKeyboard: View {
    
    @State var username = ""
    
    var body: some View {
        TextField("User name (email address)", text: $username)
        Button("Hide Keyboard") {
            endEditing()
        }
    }
    private func endEditing() {
        // Call this function on any action you want to call from.
        UIApplication.shared.endEditing()
    }
}

extension UIApplication {
    func endEditing() {
        sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
    }
}
  • Related