使用自动布局时使用 UIDynamicAnimator 制作动画

Posted

技术标签:

【中文标题】使用自动布局时使用 UIDynamicAnimator 制作动画【英文标题】:Animating with UIDynamicAnimator when Autolayout is in play 【发布时间】:2015-02-09 08:25:04 【问题描述】:

我有一个已在 InterfaceBuilder 中配置为对其所有子视图使用 AutoLayout 的 ViewController。布局工作正常。

我想使用 UIDynamicAnimator 提供的酷重力效果让其中一个子视图反弹。我认为这不适用于 AutoLayout,但我尝试了它并且确实如此。效果很好!

我的问题是,这是预期的行为吗?它会在某个地方引起问题吗? Apple 是否提供有关结合 AutoLayout 和 UIDynamicAnimators 的任何指导?

这里是代码,任何有兴趣的人:

    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】:

我的问题是,这是预期的行为吗?它会在某个地方引起问题吗? Apple 是否提供有关结合 AutoLayout 和 UIDynamicAnimators 的任何指导?

基本上,UIKit Dynamics 不能很好地配合自动布局。基本上规则是改变框架/中心与自动布局相反——这正是 UIKit Dynamics 所做的。您没有遇到问题的唯一原因是,布局碰巧不会发生在您正在制作动画的视图上。

测试方法是这样的。运行您的代码,然后(当动画完成时;可能您需要使用延迟性能)运行

self.view.layoutIfNeeded

这会导致布局发生。如果在那一刻事情发生了变化,那就暴露了问题。

【讨论】:

谢谢,马特。在这种情况下,我将某些内容重新设置为最终布局,并且在动画期间没有发生其他布局更改,因此在这种情况下使用它可能是可以的。 3 个问题: 1. 你是说如果在动画期间进行布局,那会导致问题吗? 2. 以前从未听说过“延迟性能”,但谷歌告诉我这是一回事。你能指出我的任何资源吗? 3. 如果您想为使用自动布局的视图控制器中的 UI 元素设置动画(例如弹跳或摆动),您会怎么做? @skypecakes 1. 是 - 或者如果之后发生。但是,如果您的动画将所有内容完全返回到其原始位置,您将不会看到问题,因为您所做的(使用框架)和自动布局将执行的操作(使用约束)具有相同的结果。 2.看我的书:apeth.com/iosBook/ch11.html#_delayed_performance 3.大主题,但是看我的文章:***.com/questions/12943107/… 再次感谢。我现在正在阅读您关于延迟性能的讨论。关于#1 和#3,我必须承认我对 iOS 中的动画知之甚少,无法理解您的文章,甚至我如何在动画中使用帧!我很想深入研究,花足够的时间来理解它。你是怎么学到这么多关于动画的?对刚起步的人有什么建议吗? @skypecakes 我所知道的一切,都是通过阅读(和写作)我自己的书而获得的。 :)【参考方案2】:

是的,UIDynamicAnimator 可以很好地与 AutoLayout 配合使用。我有一个严重依赖 UIDynamicAnimator 并使用约束的应用程序,它运行良好。我发现的唯一问题是 UIView animateWithDuration 不适用于约束,但该方法无论如何都不适用于 UIDynamicAnimator。 希望对你有帮助:)

【讨论】:

以上是关于使用自动布局时使用 UIDynamicAnimator 制作动画的主要内容,如果未能解决你的问题,请参考以下文章

使用自动布局时使用 UIDynamicAnimator 制作动画

Swift - 使用自动布局时获取视图框架

使用自动布局时,如何调整 CALayer 的锚点?

使用自动布局约束时,UIView 无法通过 UIpangesture 顺利拖动

为啥我的第二个按钮在使用自动布局约束时表现不同?

当 tableview 使用自动布局滚动时避免粘性标题视图