iosswiftautolayoutnslayoutconstraint

Constraints Not Updating When Keyboard Appears


I am making a sign up screen and would like to update a few top anchors so that when the keyboard appears, the top anchor constant decreases and the keyboard doesn't cover any text fields.

I have created a topConstant variable:

var constraintConstant: CGFloat = 35

And have set up my views as follows:

view.addSubview(passwordTextField)
passwordTextField.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 25).isActive = true
passwordTextField.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -25).isActive = true
passwordTextField.heightAnchor.constraint(equalToConstant: 50).isActive = true
passwordTextField.topAnchor.constraint(equalTo: emailTextField.bottomAnchor, constant: constraintConstant).isActive = true

Then I have written this code:

func textFieldDidBeginEditing(_ textField: UITextField) {
    constraintConstant = 15
    view.layoutIfNeeded()
}

I'n not sure why the constriants aren't updating. Any ideas?


Solution

  • The constant that you specify doesn't function like how you are expecting it to. You are expecting it to function like some kind of listener which will keep updating if the value of the variable is updated. It doesn't. It will just take the value of the variable at the time of setting and then not look back unless you access that constraint and change the constant manually.

    Which is why you have to store the instance of the constraint and change the constant maually.

    Define the constraint variable:

    var topAnchorConstraint: NSLayoutConstraint!
    

    Store the appropriate constraint in the variable

    topAnchorConstraint = passwordTextField.topAnchor.constraint(equalTo: emailTextField.bottomAnchor, constant: 35)
    topAnchorConstraint.isActive = true
    

    Now you need to change the constant as required.

    func textFieldDidBeginEditing(_ textField: UITextField) {
        UIView.animate(withDuration: 1.0, animations: {
            self.topAnchorConstraint.constant = 15
            self.view.layoutIfNeeded()
    
        }, completion: nil)
    }