Search code examples
swiftuiviewnslayoutconstraintuiviewanimationnsnotificationcenter

Animating constraint to push UIView above Keyboard issue


I have this CommentViewController. It's embedded in a Container View. In this CommentViewController, there's a UITableView to display comments and UIView that contains a UITextField and a UIButton. The UIView that's containing those 2 objects is fixed via autolayout in the bottom, right and left to the Safe Area and top to the UITableView.

Now, when the user taps the UITextField, the whole view (with the button and the textfield inside) should be lifted above the keyboard. I'm trying to animated the bottom constraint of the view, but it's not working.

This is the code:

override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

}

@objc func keyboardWillShow(_ notification: NSNotification) {
    let keyboardFrame = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as AnyObject).cgRectValue
    UIView.animate(withDuration: 0.3) {
        self.textFieldViewBottomConstraint.constant = keyboardFrame!.height
    }
}

This is storyboard:

enter image description here

This is the result after you tap the text field.

enter image description here

PS: when I tap on UITextField, the console shows this message:

2018-06-04 14:11:52.471848+0300 AppName[91846:8829073] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /Users/d/Library/Developer/CoreSimulator/Devices/C89347A2-1598-4F31-BBAC-1F98F970A248/data/Containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles 2018-06-04 14:11:52.472588+0300 Shippers[91846:8829073] [MC] Reading from private effective user settings.


Solution

  • You need to call self.view.layoutIfNeeded() after changing the constraint's constant

    self.textFieldViewBottomConstraint.constant = keyboardFrame!.height
       UIView.animate(withDuration: 0.3) {
        self.view.layoutIfNeeded()
    }
    

    //

     NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow(_:)), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
    

    Edit:

    Setting constant property for the bottom constraint depends on which element is the first in the constraint so if the constraint looks like this

    Here textfield is the first

    textfield_Bottom = view_Bottom * multiplier + constant. —> then constant must be minus as Y axis decrease when go to up which what we want to make the view goes up when keyboard is shown

    Here view is the first

    view_Bottom = textfield_Bottom * multiplier + constant. —> then constant must be plus