Animate `backgroundColor` of a `UIView` that implements `drawRect`

It is indeed not working when I try it, I had a related question where putting the layoutIfNeeded() method inside the animation worked and made the view smoothly animating (move button towards target using constraints, no reaction?). But in this case, with the backgroundColor, it does not work. If someone knows the answer I will be interested to know.

But if you need a solution right now, you could create a UIView (programmatically or via the storyboard) that is used only as a container. Then you add 2 views inside : one on top, and one below, with the same frame as the container. And you only change the alpha of the top view, which let the user see the view behind :

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")
        }
    }
}

The answer is that you cannot animate backgroundColor of a view that implements drawRect. I do not see docs for this anywhere (please comment if you know of one).

You can't animate it with animateWithDuration, nor with Core Animation.

This thread has the best explanation I've found yet:

When you implement -drawRect:, the background color of your view is then drawn into the associated CALayer, rather than just being set on the CALayer as a style property... thus prevents you from getting a contents crossfade

The solution, as @Paul points out, is to add another view above, behind, or wherever, and animate that. This animates just fine.

Would love a good understanding of why it is this way and why it silently swallows the animation instead of hollering.