【问题标题】:Swift: Core Animation not animatingSwift:核心动画没有动画
【发布时间】:2017-06-21 03:05:33
【问题描述】:

谈到核心动画,我是个菜鸟。我正在尝试实现简单的动画,其中UILabel 从 A 点移动到 B 点。我有以下从动画代码示例中获得的代码,但我无法让它工作。标签根本不动。我做错了什么?

let frame = self.view.frame
let blueBox = UIView(frame: frame)
blueBox.backgroundColor = UIColor(red:  46/255, green: 83/255, blue: 160/255, alpha: 1.0)

let label = UILabel(frame: CGRect(x: 0, y: 0, width: 300, height: 400))
label.center = CGPoint(x: frame.size.width/2, y: frame.size.height/2)
label.textAlignment = .center
label.lineBreakMode = .byWordWrapping
label.numberOfLines = 0

label.layer.position = label.center

var attrsA = [NSFontAttributeName: UIFont(name: "LemonMilk", size: 92), NSForegroundColorAttributeName: UIColor.white]
var a = NSMutableAttributedString(string:"Hello\n", attributes:attrsA)
var attrsB =  [NSFontAttributeName: UIFont(name: "LemonMilk", size: 38), NSForegroundColorAttributeName: UIColor.white]
var b = NSAttributedString(string:"World", attributes:attrsB)
a.append(b)


label.attributedText = a

let theAnimation = CABasicAnimation(keyPath: "position");
theAnimation.fromValue = [NSValue(cgPoint: CGPoint(x: screenWidth/2, y: screenHeight/2))]
theAnimation.toValue = [NSValue(cgPoint: CGPoint(x: 100.0, y: 100.0))]
theAnimation.duration = 3.0;
theAnimation.autoreverses = false //true - reverses into the initial value either smoothly or not
theAnimation.repeatCount = 2

blueBox.addSubview(label)

view.addSubview(blueBox)
label.layer.add(theAnimation, forKey: "animatePosition");

【问题讨论】:

  • 使用UIView.animate(withDuration:)可能会容易得多
  • @Pierce 但这并不能回答问题
  • @matt - 我知道这就是我没有回答的原因。我只是在 cmets 中提出建议
  • @matt - 你有什么问题?下车,再去读我的评论。我从来没有说过“不要那样做”,我只是提出了一种可能更容易让他们实现目标的方法的建议。他说他是新手。我没有给他一个不能解决他问题的答案,我也从来没有告诉他他不能做他正在尝试的事情。我所说的“可能会更容易”尝试另一种选择。
  • @matt - 您的评论暗示建议和寻找替代方案是不合理的 - 这本质上是错误的。

标签: ios swift uiview core-graphics core-animation


【解决方案1】:

首先:您不能同时在label 上调用addSubviewlabel.layer 上的add(animation:)。您只能为视图层次结构中已经的视图设置动画。换句话说,即使您的代码一切正常,您还是调用add(animation:)太快了。尝试引入delay

第二:这些行是假的:

theAnimation.fromValue = [NSValue(cgPoint: CGPoint(x: screenWidth/2, y: screenHeight/2))]
theAnimation.toValue = [NSValue(cgPoint: CGPoint(x: 100.0, y: 100.0))]

fromValuetoValue 都不能是 数组。摆脱那些牙套。在 Swift 3.0.1 及更高版本中,您也不需要强制使用 NSValue。所以:

theAnimation.fromValue = CGPoint(x: screenWidth/2, y: screenHeight/2)
theAnimation.toValue = CGPoint(x: 100.0, y: 100.0)

第三fromValue 是干什么用的?如果您想从标签所在的位置开始制作动画,只需省略 fromValue

因此,我将您的代码修改为这样结束,并且我看到了动画:

label.attributedText = a
blueBox.addSubview(label)
view.addSubview(blueBox)
delay(1) {
    let theAnimation = CABasicAnimation(keyPath: "position");
    theAnimation.toValue = CGPoint(x: 100.0, y: 100.0)
    theAnimation.duration = 3.0;
    theAnimation.autoreverses = false //true - reverses into the initial value either smoothly or not
    theAnimation.repeatCount = 2
    label.layer.add(theAnimation, forKey: "animatePosition");
}

【讨论】:

  • 我认为,动画仍然无法实现您想要的效果,但至少有了这些建议,您应该看到会发生一些事情。如果没有,请告诉我。
  • 延迟解决了我的问题,但必须有更好的方法。这似乎是一个丑陋的黑客。是否有一个事件或我可以听到的内容是“一切都已设置,您现在可以添加动画”?我到底在等什么?
  • 嗨@Kerndog73 - 您正在等待运行循环完成。我认为,更短的延迟(0.1)应该也可以。或者您可以尝试只刷新当前事务;这告诉布局引擎在继续之前将所有内容都准备好,这是我有时使用的一种技术。
  • 感谢您的快速回复。我该怎么做?
  • 我想你会说 CATransaction.flush() 但不要引用我的话。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-21
  • 2011-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-16
相关资源
最近更新 更多