实现`drawRect`的`UIView`的动画`backgroundColor`

我有一个自定义UIView,我想动画其backgroundColor属性。 这是UIView的动画属性 。

这是代码:

 class ETTimerUIView: UIView { required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } // other methods func flashBg() { UIView.animateWithDuration( 1.0, animations: { self.backgroundColor = UIColor.colorYellow() }) } override func drawRect() { // Something related to a timer I'm rendering } 

此代码导致动画跳过并且颜色立即更改:

 self.backgroundColor = UIColor.colorYellow() // Changes immediately to yellow 

如果我为alpha设置动画,则会按预期在1秒内激活1到0:

 self.alpha = 0 // animates 

在这种情况下,如何设置背景颜色变化的动画?

  • 实现drawRect阻止backgroundColor动画 ,但尚未提供答案。
  • 也许这就是为什么你不能组合drawRectanimateWithDuration ,但我不太了解它。

我想我需要制作一个单独的视图 – 这应该放在同一个视图控制器的故事板中吗? 以编程方式创建?

对不起,我是iOS和Swift的新手。

当我尝试它时确实不起作用,我有一个相关的问题,在动画中放置layoutIfNeeded()方法并使视图平滑动画( 使用约束移动按钮朝向目标,没有反应? )。 但在这种情况下,使用backgroundColor,它不起作用。 如果有人知道答案我会有兴趣知道。

但是,如果您现在需要解决方案,则可以创建仅用作容器的UIView(以编程方式或通过故事板)。 然后在里面添加2个视图:一个在顶部,一个在下面,与容器具有相同的框架。 并且您只更改顶视图的alpha,让用户看到后面的视图:

 class MyView : UIView { var top : UIView! override init(frame: CGRect) { super.init(frame: frame) self.backgroundColor = UIColor.blueColor() top = UIView(frame: CGRectMake(0,0, self.frame.width, self.frame.height)) top.backgroundColor = UIColor.yellowColor() self.addSubview(top) } override func touchesBegan(touches: NSSet, withEvent event: UIEvent) { let sub = UIView(frame: CGRectMake(0,0, self.frame.width, self.frame.height)) sub.backgroundColor = UIColor.purpleColor() self.sendSubviewToBack(sub) UIView.animateWithDuration(1, animations: { () -> Void in self.top.alpha = 0 }) { (success) -> Void in println("anim finished") } } } 

答案是您无法为实现drawRect的视图设置backgroundColor动画。 我没有在任何地方看到这方面的文件(如果你知道一个,请发表评论)。

您无法使用animateWithDuration或Core Animation animateWithDuration设置动画。

这个post有我发现的最好的解释:

当您实现-drawRect:时,视图的背景颜色将被绘制到关联的CALayer中,而不是仅仅作为样式属性在CALayer上设置…从而阻止您获取内容交叉淡入淡出

正如@Paul指出的那样,解决方案是在上面,后面或者任何地方添加另一个视图,并为其设置动画。 这动画很好。

希望能够很好地理解为什么会这样,以及为什么它会默默地吞下动画而不是大喊大叫。