我有自定义UIView,我想为其backgroundColor
属性设置动画。这是UIView
的{{3}}。
这是代码:
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
如何在这种情况下为背景颜色变化设置动画?
我想我需要制作一个单独的视图 - 这应该放在同一个视图控制器的故事板中吗?以编程方式创建?
对不起,我是iOS和Swift的新手。
答案 0 :(得分:4)
当我尝试它时确实不起作用,我有一个相关的问题,即在动画中放置layoutIfNeeded()方法并使视图平滑地动画化(move button towards target using constraints, no reaction?)。但在这种情况下,使用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")
}
}
}
答案 1 :(得分:2)
答案是,您无法为实现backgroundColor
的视图的drawRect
设置动画。我没有在任何地方看到这方面的文件(如果你知道一个,请发表评论)。
您无法使用animateWithDuration
或Core Animation为其设置动画。
This thread有我发现的最佳解释:
当您实现-drawRect:时,视图的背景颜色会被绘制到关联的CALayer中,而不是仅仅作为样式属性在CALayer上设置...从而阻止您获取内容交叉渐变
正如@Paul指出的那样,解决方案是在上方,后方或任何地方添加另一个视图,并为其设置动画。这动画很好。
会喜欢很好地理解为什么会这样,以及为什么它会默默地吞下动画而不是大喊大叫。
答案 2 :(得分:1)
不确定这是否适合您,但为了给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