在 Swift 中使用 CoreAnimation 为 UILabel 元素设置动画

Posted

技术标签:

【中文标题】在 Swift 中使用 CoreAnimation 为 UILabel 元素设置动画【英文标题】:Animating UILabel element with CoreAnimation in Swift 【发布时间】:2014-06-22 17:24:44 【问题描述】:

我正在学习如何将 CoreAnimation 与各种 UI 元素一起使用。最终,当我转换到下一个视图时,我想在屏幕上的所有 ui 元素上执行复杂的排队动画。

但是现在我正在尝试一些非常简单的事情。我想在点击按钮时转换(放大)一个 UILabel。

我有以下功能:

func animateUIElementsOut(element : AnyObject) 

  var animation : CABasicAnimation = CABasicAnimation(keyPath: "transform");

  var transform : CATransform3D = CATransform3DMakeScale(2, 2, 1);

  animation.setValue(NSValue(CATransform3D: transform), forKey: "scaleText");

  animation.duration = 2.0;

  element.layer?.addAnimation(animation, forKey: "scaleText");


我在这样的按钮点击上调用该函数:

  animateUIElementsOut(greetingsLabel);

编译器没有发出任何警告,但是动画不起作用。我在这里做错了什么?

根据@David Rönnqvist 的建议,工作代码如下所示(添加了 fromValue / toValue):

func animateUIElementsOut(element : AnyObject) 

  var animation : CABasicAnimation = CABasicAnimation(keyPath: "transform");

  animation.delegate = self;

  var transform : CATransform3D = CATransform3DMakeScale(2, 2, 1);

  animation.fromValue = NSValue(CATransform3D: CATransform3DIdentity);
  animation.toValue = NSValue(CATransform3D: transform);

  animation.duration = 2.0;

  element.layer?.addAnimation(animation, forKey: nil);

【问题讨论】:

【参考方案1】:

动画既没有toValue 也没有fromValue

您正在为动画上的"scaleText" 键设置变换,但动画没有相应的属性。

要使动画 本身工作,您应该将变换设置为动画的toValue。但是,仍然缺少一些东西来使整个事情正常工作。图层的模型值永远不会更改,因此当动画完成并被移除时,您将再次看到旧的(模型)值。

如果您只对制作缩放动画感兴趣,我建议您改用更高级别的 UIView 动画 API:

UIView.animateWithDuration(2.0) 
    element.transform = CGAffineTransformMakeScale(2, 2)

另一方面,如果您对使用 Core Animation 感兴趣,还需要做更多的事情来完成所有工作。

    将动画配置为当前模型值(使用fromValue 属性) 将动画配置为新值(如上所述) 在添加动画之前将模型值更新为新值。

顺便说一句,您可以在没有任何此类属性的情况下为“scaleText”设置值的原因是图层和动画的工作方式与大多数使用键值编码的类有点不同。您可以使用键值编码在图层和视图上设置和获取任何值。这意味着这是有效的代码:

let layer = CALayer()
layer.setValue(1, forKey: "foo")
var foo = layer.valueForKey("foo") // is equal to 1

let anim = CABasicAnimation(keyPath: "bounds")
anim.setValue(2, forKey: "bar")
var bar = anim.valueForKey("bar") // is equal to 2

但是,如果您尝试对几乎任何其他对象执行相同操作,您将收到运行时异常,指出该类不符合该键的键值编码。例如这段代码:

let view = UIView(frame: CGRectZero)
view.setValue(3, forKey: "baz")

产生此运行时异常:

Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UIView 0x10dc08b30> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key baz.'

【讨论】:

大卫谢谢你的回复。这些“forKey”/“keyPath”值肯定让我很吃惊,所以我必须阅读更多关于这些的内容。好在你帮我成功触发了我的动画,所以我会试着从那里开始。再次感谢您抽出宝贵时间回复! @MartinVelchevski 动画的关键路径就是您要制作的动画。使用添加动画时使用的键,以便您可以引用和手动删除动画。

以上是关于在 Swift 中使用 CoreAnimation 为 UILabel 元素设置动画的主要内容,如果未能解决你的问题,请参考以下文章

Swift coreAnimation 加计时器写的游戏《飞机大战》

图书┃Swift与Cocoa框架开发

CoreAnimation汇总

CloudKit CoreAnimation 错误

在 iOS 应用程序中使用 CoreAnimation / QuartzCore 动画 UILabel

如何在 Swift 中创建具有自定义形状的 UIButton?