Crocobag
Crocobag

Reputation: 2340

UIView animateKeyframes not working with NSLayoutConstraints

I'm trying to animate a UIView by reducing it's width constraint, but it doesn't works well when using UIView.animateKeyFrames. Here is my code :

    UIView.animateKeyframes(withDuration: 2.0, delay: 0, options: [.calculationModeCubic], animations: {
        UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 1.0/2.0, animations: {
            self.titleLabel.alpha = 0.0 // works well
        })

       self.titleSquareHeightConstraint?.constant = 20 // previously 170
        UIView.addKeyframe(withRelativeStartTime: 1.0/2.0, relativeDuration: 1.0/2.0, animations: {
            self.titleSquare.layoutIfNeeded() // instantaneously jump to 20
        })

    }, completion:nil)

The titleSquare's height will jump from 170 to 20 instantaneously. Note: titleSquare is a UIView. Also, I used to work with UIView.animate and the code below works just fine :

    self.titleSquareHeightConstraint?.constant = 20
    UIView.animate(withDuration: 0.5,
                   delay: 0,
                   usingSpringWithDamping: 1,
                   initialSpringVelocity: 1,
                   options: .curveEaseIn,
                   animations: {

                    self.view.layoutIfNeeded() // Perfectly works

    },completion: nil)

What am I doing wrong with my UIView.animateKeyframes method? It seems I don't get completely how it works?

Thanks

Upvotes: 1

Views: 789

Answers (1)

DonMag
DonMag

Reputation: 77462

Not completely obvious or intuitive, but...

You want to tell the view to layoutIfNeeded():

    UIView.animateKeyframes(withDuration: 2.0, delay: 0, options: [.calculationModeCubic], animations: {

        UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 1.0/2.0, animations: {
            self.titleLabel.alpha = 0.0 // works well
        })

        self.titleSquareHeightConstraint.constant = 20 // previously 170

        UIView.addKeyframe(withRelativeStartTime: 1.0/2.0, relativeDuration: 1.0/2.0, animations: {

            // tell self.view to layout, not the titleSquare view
            self.view.layoutIfNeeded()

        })

    }, completion:nil)

Upvotes: 4

Related Questions