UIView 框架的 CASpringAnimation

Posted

技术标签:

【中文标题】UIView 框架的 CASpringAnimation【英文标题】:CASpringAnimation for UIView frame 【发布时间】:2017-01-15 15:33:01 【问题描述】:

我正在使用此代码为带有弹簧动画的视图设置动画,但它似乎没有这样做。视图在没有任何“弹簧”动画的情况下捕捉到框架。

之前您建议这样做:

UIView.animate(withDuration: 0.65, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 3.0, options: .curveEaseOut , animations: ...

我只想告诉你,我的视图使用cornerRadius,所以我不能用上面的动画cornerRadius!

 magnifyView (layer: CALayer, size: CGSize) 

     let oldBounds = layer.bounds
        var newBounds = oldBounds
        newBounds.size = size

        let animateFrame = CASpringAnimation(keyPath: "transform.scale")

        animateFrame.fromValue = NSValue(cgRect: oldBounds)
        animateFrame.toValue = NSValue(cgRect: newBounds)
        animateFrame.damping = 0.65
        animateFrame.initialVelocity = 3.0
        animateFrame.duration = animateFrame.settlingDuration


            layer.add(animateFrame, forKey: "transform.scale")
             layer.bounds = newBounds


【问题讨论】:

【参考方案1】:

你的动画是错误的。您将 key path 设置为 transform.scale,这将是一个 CGFloat,它会导致整个视图改变大小。

然后插入 CGRects 的 fromValue 和 toValue NSValue。我怀疑您在运行该代码时会在控制台中收到错误。

如果要为框架设置动画,请为框架设置动画。 (不是边界,框架。)使用

let oldFrame = layer.frame

...

let animateFrame = CASpringAnimation(keyPath: "frame")

...

animateFrame.fromValue = NSValue(cgRect: oldFrame)
animateFrame.toValue = NSValue(cgRect: newFrame)

...

layer.frame = newFrame

编辑:

使用问题开头提到的 UIView 动画当然更容易做到这一点。试试这样的代码:

class ViewController: UIViewController 

  var isLarge: Bool = false
  @IBOutlet weak var roundLabel: UILabel!

  @IBAction func handleResizeButton(_ sender: UIButton) 
    isLarge = !isLarge
    let size: CGFloat = isLarge ? 1.5 : 1.0
    UIView.animate(withDuration: 0.65, delay: 0, 
      usingSpringWithDamping: 0.6, 
      initialSpringVelocity: 3.0, 
      options: .curveEaseOut, 
      animations: 
        self.roundLabel.transform = CGAffineTransform(scaleX: size, y: size)
      
    )
  

【讨论】:

我的控制台没有错误。将边界更改为帧对我的动画没有影响(仍然是快照而不是弹簧) 请注意,您还需要更改用于创建动画的 keyPath。 如果您使用自动布局,则更改框架将无法按预期工作。视图上的约束将接管并将帧更改为最终值,覆盖动画。您应该在视图的 x 和 7 位置上使用 UIView 动画和动画约束。 你说“我只是想告诉你我的视图使用cornerRadius,所以我不能用上面的动画cornerRadius!”我不知道那是什么意思。您发布的代码不会改变您视图的cornerRadius,所以我不确定您的意思。您可以使用 UIView 动画为具有非零角半径的视图设置动画,并且效果很好。 不,你是对的。这不是完成的代码。我只是想明确一点,我想将cornerRadius 动画化为框架......

以上是关于UIView 框架的 CASpringAnimation的主要内容,如果未能解决你的问题,请参考以下文章

是否可以将带有大框架的uiview添加到带有小框架的uiview中

如何获取嵌套在 UIView 中的 UIView 框架 - Objective C

动画父 UIView 的框架(大小)时自动调整 UILabel 的框架

Swift - UIView 框架不等于 UIView.layer.frame

除非等于 UIView 框架,否则框架不会正确更改

为 UIView 框架编写单元测试