views:

29

answers:

2

I'm crossfading between two views using UIView animation. I've noticed the following surprising fact:

If I have (say) two identical views in an identical place, and I animate a cross fade between them (e.g. animate the alpha from 0.0 to 1.0 on one while going from 1.0 to 0.0 on the other, in the same animation), during the animation, the visible result arcs slightly below opaque during the animation-- this is a noticeable artifact and can be verified by putting some other view behind the crossfaded views (it becomes visible briefly during the animation before being obscured again).

I would expect (using any animation timing curve) that perfectly paired 0->1 and 1->0 alpha transitions would always add up to a net alpha of 1.0, and that in this test situation, I should never see any visible change in alpha, yet I do.

Any idea what's going on here? I could hack around this for a "fix", but I'm mostly interested in what I'm missing conceptually in the blending.

Thanks!

A: 

This is just a guess with no basis in actual fact, but since alpha is expressed as a CGFloat, I would advise against trying to assume anything about it adding up to 1.0 exactly, given the difficulty representing floating points with that type of precision. They likely add up to .99 or so, causing this artifact.

Jeff Kelley
This is more visible than a float precision issue. Per jtbande's answer, it was more like .75 or so :)
quixoto
+3  A: 

Two stacked views with alphas adding up to 1.0 doesn't do what you think it does. They are multiplied, not added.

Let's take it a chunk at a time. Here's a background, shining through 100%:

bg
|======>
|======>
|======>
|======>

Now let's add another view on top, 50% opacity. That means it lets 50% of the background through

bg 50%
|===|===>
|===|
|===|===>
|===|

What if we have another 50% view on top?

bg 50% 50%
|===|===|===>
|===|   |
|===|===|
|===|   |

Another 50% of the stuff behind is passed through. This means that 50% × 50% = 25% of the background layer will still be showing through.

Now, what do you really want to do? You want the new view to appear smoothly, an increasing amount passing through the old view. So just stack the two views, and fade out the top one, but leave the bottom at 100% opacity the whole time. Otherwise you'll be showing some of the background through during the animation.

jtbandes
You had me at "multiplied, not added". :) Thanks, clear explanation and I wish I could give more points for including the great diagrams.
quixoto