Hapeki
Hapeki

Reputation: 2193

Resize constraint with keyboard animation

I'm trying to animate my UIStackView which contains a login form whenever the keyboard appears. I want to do it only by adjusting constraints from my storyboard file.

This is my layout:

Layout

My code resizes the bottom constraint depending on the size of the keyboard.

@IBOutlet var keyboardHeightLayoutConstraint: NSLayoutConstraint!

override func viewDidLoad() {
    super.viewDidLoad()

    NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardNotification(notification:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)

    keyboardHeightLayoutConstraint.isActive = false
}

func keyboardNotification(notification: NSNotification) {
    keyboardHeightLayoutConstraint.isActive = true
    if let userInfo = notification.userInfo {
        let endFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
        let duration:TimeInterval = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
        let animationCurveRawNSN = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber
        let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIViewAnimationOptions.curveEaseInOut.rawValue
        let animationCurve:UIViewAnimationOptions = UIViewAnimationOptions(rawValue: animationCurveRaw)

        if (endFrame?.origin.y)! >= UIScreen.main.bounds.size.height {
            self.keyboardHeightLayoutConstraint?.constant = 0.0
        } else {
            self.keyboardHeightLayoutConstraint?.constant = (endFrame?.size.height)! + 20
        }
        UIView.animate(withDuration: duration,
                       delay: TimeInterval(0),
                       options: animationCurve,
                       animations: { self.view.layoutIfNeeded() },
                       completion: nil)
    }
}

The result is that it only shrinks the size of the UIStackView because the top constraint wont allow it to move upwards, example:

Result

This has to do with the top constraint of my stackview. Deleting this constraint solves the problem but on smaller resolutions the form might overlap with the UIImageView. Is there a way to update this constraint to reflect the changes of the bottom constraint?

Upvotes: 2

Views: 788

Answers (2)

Duncan C
Duncan C

Reputation: 131418

You can set up outlets to both the top and bottom constraints and change them both. I've done that a number of times.

I'm not totally clear on your constraint layout, but I'm guessing that you want to add to the bottom layout's constraint and subtract from the top layout constraint.

Upvotes: 1

rob mayoff
rob mayoff

Reputation: 385590

Lower the priority of that constraint (the one from the image view to the stack view) to 200. A priority of 200 is lower than the default content compression priorities, so autolayout will break it before squishing other views.

Upvotes: 0

Related Questions