2

I have a full screen UITableView that is pinned top, bottom, trailing and leading. This ViewController is inside a navigation controller. I want the bottom of the table to move up and animate with the keyboard as it appears. I have the following code:

    // MARK: Keyboard

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

    func unregisterObservers() {
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
    }

    func keyboardWillShow(_ notification: Notification) {
        let keyboardFrame = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
        let keyboardAnimationDuration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber
        let keyboardAnimationCurve = notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber
        tableViewBottomConstraint.constant = keyboardFrame.height
        UIView.animate(withDuration: TimeInterval(keyboardAnimationDuration), delay: 0, options: [UIViewAnimationOptions(rawValue: UInt(keyboardAnimationCurve))], animations: {
            self.view.layoutIfNeeded()
        }, completion: { (finished: Bool) in
        })
    }

    func keyboardWillHide(_ notification: Notification) {
        let keyboardAnimationDuration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber
        let keyboardAnimationCurve = notification.userInfo?[UIKeyboardAnimationCurveUserInfoKey] as! NSNumber
        tableViewBottomConstraint.constant = 0
        UIView.animate(withDuration: TimeInterval(keyboardAnimationDuration), delay: 0, options: [UIViewAnimationOptions(rawValue: UInt(keyboardAnimationCurve))], animations: {
            self.view.layoutIfNeeded()
        }, completion: { (finished: Bool) in
        })
    }

I register the observers on ViewDidLoad. The animation appears to be quite jerky when the keyboard appears. However the dismiss animation does not seem to have any issues. What am I doing wrong here? Am I setting the animation duration or curve wrong?

KexAri
  • 3,867
  • 6
  • 40
  • 80

1 Answers1

5

I have done this by doing the following:

declare an IBOutlet variable for the bottom constraint. Be sure to link the appropriate constraint which for your case is the bottom constraint of your tableView.

@IBOutlet weak var bottomConstraint: NSLayoutConstraint!

Add a function to handle the adjustments.

    func keyboardChangeFrame(_ notification: Notification) {
    let endFrame = ((notification as NSNotification).userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
    bottomConstraint.constant = view.bounds.height - endFrame.origin.y
    self.view.layoutIfNeeded()
}

And lastly, in viewDidLoad add UIKeyboardWillChangeFrame observer.

    NotificationCenter.default.addObserver(self
        , selector: #selector(keyboardChangeFrame)
        , name: NSNotification.Name.UIKeyboardWillChangeFrame
        , object: nil)
Kiester
  • 147
  • 1
  • 7