Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animating with UIDynamicAnimator when Autolayout is in play

I have a ViewController that has been configured in InterfaceBuilder to use AutoLayout for all of its subviews. Layout is working fine.

I want to make one of the subviews bounce using the cool gravity effects provided by UIDynamicAnimator. I didn't think that would work with AutoLayout, but I tried it and it does. It works quite well!

My question is, is this the expected behavior? Is it going to cause problems somewhere? Does Apple provide any guidance around combining AutoLayout and UIDynamicAnimators?

Here is the code, for anyone interested:

    var boundaryFrame = self.buttonBackgroundView.frame
    boundaryFrame = CGRect(x: 0,
        y: boundaryFrame.origin.y + (boundaryFrame.height + 1),
        width: self.view.frame.width,
        height: 2)

    self.animator = UIDynamicAnimator(referenceView: self.view)
    var gravity = UIGravityBehavior(items: [self.buttonBackgroundView])
    gravity.magnitude = 0.5

    var collision = UICollisionBehavior(items: [self.buttonBackgroundView])
    var boundaryId: NSMutableString = NSMutableString(string: "bottomBoundary")
    let boundaryPath = UIBezierPath(rect: boundaryFrame)
    collision.addBoundaryWithIdentifier(boundaryId, forPath: boundaryPath)

    let bounceProperties = UIDynamicItemBehavior(items: [self.buttonBackgroundView])
    bounceProperties.elasticity = 0.5

    // Move it up before causing it to bounce down to its original location
    self.setMeUpTopConstraint.constant = 10
    self.view.setNeedsUpdateConstraints()
    self.view.layoutIfNeeded()

    // Start animating
    animator.addBehavior(gravity)
    animator.addBehavior(collision)
    animator.addBehavior(bounceProperties)
like image 757
stone Avatar asked Feb 09 '15 08:02

stone


1 Answers

My question is, is this the expected behavior? Is it going to cause problems somewhere? Does Apple provide any guidance around combining AutoLayout and UIDynamicAnimators?

Basically, UIKit Dynamics does not play well with auto layout. Basically the rule is that changing the frame / center of something is contrary to auto layout - and that is exactly what UIKit Dynamics does. The only reason you are not encountering a problem is that, by chance, layout does not happen to be occurring on the view(s) you are animating.

The way to test is this. Run your code, and then (when the animation has finished; possibly you'll need to be using delayed performance) run

self.view.layoutIfNeeded

That causes layout to happen. If things jump around at that moment, it exposes the issue.

like image 65
matt Avatar answered Nov 09 '22 19:11

matt