Animating with UIDynamicAnimator when Autolayout i

2019-06-19 02:20发布

问题:

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)

回答1:

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.



回答2:

Yes, UIDynamicAnimator works fine with AutoLayout. I have an app that relies heavily on UIDynamicAnimator and uses constraints, and it has worked fine. The only issue I have found is that UIView animateWithDuration doesn't work with constraints, but that method doesn't work well with UIDynamicAnimator anyways. Hope it helps :)