我有一个自定义的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到0设置动画:
self.alpha = 0 // animates
在这种情况下,如何设置背景颜色变化的动画?
- 实现
drawRect
阻止backgroundColor动画,但还没有提供答案 - 也许这就是为什么你不能把
drawRect
和animateWithDuration
结合起来,但我不太理解
我想我需要制作一个单独的视图——这应该放在同一个视图控制器的故事板中吗?以编程方式创建?
对不起,我真的是iOS和Swift的新手。
当我尝试它时,它确实不起作用,我有一个相关的问题,在动画中放置layoutIfNeedd()方法在哪里起作用,并使视图平滑地设置动画(使用约束将按钮移向目标,没有反应?)。但在这种情况下,使用backgroundColor是不起作用的。如果有人知道答案,我很想知道。
但是,如果您现在需要一个解决方案,您可以创建一个UIView(以编程方式或通过情节提要),它仅用作容器。然后在里面添加两个视图:一个在上面,一个在下面,框架与容器相同。您只需更改顶部视图的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
或"核心动画"设置它的动画。
这个帖子有我发现的最好的解释:
当您实现-drawRect:时,视图的背景色将被绘制到关联的CALayer中,而不仅仅是在CALayer上设置为样式属性。。。从而防止您获得内容交叉的
正如@Paul所指出的,解决方案是在上面、后面或任何地方添加另一个视图,并将其设置为动画。这个动画效果很好。
我希望能很好地理解为什么它会这样,为什么它会默默地吞下动画而不是大喊大叫。
不确定这是否适用于您,但为了使UIView的背景色动画化,我将其添加到UIView扩展中:
extension UIView {
/// Pulsates the color of the view background to white.
///
/// Set the number of times the animation should repeat, or pass
/// in `Float.greatestFiniteMagnitude` to pulsate endlessly.
/// For endless animations, you need to manually remove the animation.
///
/// - Parameter count: The number of times to repeat the animation.
///
func pulsate(withRepeatCount count: Float = 1) {
let pulseAnimation = CABasicAnimation(keyPath: "backgroundColor")
pulseAnimation.fromValue = <#source UIColor#>.cgColor
pulseAnimation.toValue = <#target UIColor#>.cgcolor
pulseAnimation.duration = 0.4
pulseAnimation.autoreverses = true
pulseAnimation.repeatCount = count
pulseAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
self.layer.add(pulseAnimation, forKey: "Pulsate")
CATransaction.commit()
}
}
将其粘贴到Xcode中的源文件时,请将占位符替换为所需的两种颜色。或者,您可以用以下值替换整行:
pulseAnimation.fromValue = backgroundColor?.cgColor
pulseAnimation.toValue = UIColor.white.cgColor