Graphics Reference
In-Depth Information
animation.
keyPath
=
@"transform"
;
animation.
toValue
= [
NSValue
valueWithCATransform3D
:transform];
animation.
duration
=
0.5
;
animation.
delegate
=
self
;
[animation
setValue
:handView
forKey
:
@"handView"
];
[handView.
layer
addAnimation
:animation
forKey
:
nil
];
}
else
{
//set transform directly
handView.
layer
.
transform
= transform;
}
}
- (
void
)animationDidStop:(
CABasicAnimation
*)anim finished:(
BOOL
)flag
{
//set final position for hand view
UIView
*handView = [anim
valueForKey
:
@"handView"
];
handView.
layer
.
transform
= [anim.
toValue
CATransform3DValue
];
}
@end
We've successfully identified when each layer has finished animating and updated its
transform to the correct value. So far, so good.
Unfortunately, even after taking those steps, we have another problem. Listing 8.4 works
fine on the simulator, but if we run it on an iOS device, we can see our clock hand snap
back to its original value briefly before our
-animationDidStop:finished:
delegate
method is called. The same thing happens with the layer color in Listing 8.3.
The problem is that although the callback method is called after the animation has finished,
there is no guarantee that it will be called before the property has been reset to its pre-
animation state. This is a good example of why you should always test animation code on a
device, not just on the simulator.
We can work around this by using a property called
fillMode
, which we explore in the
next chapter, but the lesson here is that setting the animated property to its final value
immediately
before
applying the animation is a much simpler approach than trying to
update it after the animation has finished.