iOS Keyboard Flickering when using textField.textContentType

Viewed 268

I've picked up on a weird little bug that I can't fix. When moving between textfields, the toolbar (associated as the textfield's input accessory view) and keyboard are flickering. It's only happening on a physical device, specifically when the textfield's textContentType = .password and when using code to move between textfields, e.g. in this case, the "Jump" toobar button which flips between textFields. I'm attaching a couple of screenshots that show what the glitch shows. It basically collapses the auto-complete Passwords toolbar for a micro second and then shows it again:

When .textContentType is NOT set When .textContentType is set

I've tested other code to move the cursor to the password textfield and it too shows the same glitch. I think it's something to do with calling .becomeFirstResponder but I can't work out how to fix it. It's happening not just with the .password option of .textContentType but also others, e.g. .username, .familyName. I need to fix it because, not only does it cause that slight screen glitch, but in my full project, I have a bunch of other stuff on the screen that moves based on the location of the keyboard and this glitch triggers the keyboard observer which in turn update the keyboard frame.

I've created a blank project and the same issue happens. Here is the code. If anyone can help, it would be greatly appreciated.

class ViewController: UIViewController {

    var keyboardToolbar: UIToolbar!
    var emailTextField : UITextField!
    var passwordTextField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        keyboardToolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
        let jumpButton = UIBarButtonItem(title: "Jump", style: .plain, target: self, action: #selector(jumpToolBarButtonTapped))
        keyboardToolbar.items = [jumpButton]
        keyboardToolbar.sizeToFit()

        emailTextField = UITextField()
        emailTextField.placeholder = "Email Address TextField"
        emailTextField.keyboardType = .emailAddress
        emailTextField.textContentType = .emailAddress
        emailTextField.autocapitalizationType = .none
        emailTextField.inputAccessoryView = keyboardToolbar
        
        view.addSubview(emailTextField)
        emailTextField.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            emailTextField.topAnchor.constraint(equalTo: view.topAnchor, constant: 100),
            emailTextField.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
            emailTextField.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10),
        ])
        
        passwordTextField = UITextField()
        passwordTextField.placeholder = "Password TextField"
        passwordTextField.keyboardType = .default
        passwordTextField.autocapitalizationType = .none
        passwordTextField.textContentType = .password
        passwordTextField.inputAccessoryView = keyboardToolbar

        view.addSubview(passwordTextField)
        passwordTextField.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            passwordTextField.topAnchor.constraint(equalTo: emailTextField.bottomAnchor, constant: 20),
            passwordTextField.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
            passwordTextField.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10),
        ])
    }
    
    
    @objc func jumpToolBarButtonTapped() {
        if emailTextField.isFirstResponder == true{
            DispatchQueue.main.async { [self] in
                passwordTextField.becomeFirstResponder()
            }
        } else {
            DispatchQueue.main.async { [self] in
                emailTextField.becomeFirstResponder()
            }
        }
    }
}
0 Answers
Related