553CAAnimation and the Snapback Problem

Having previously done Core Animation only on the iPhone, I am still a beginner when it comes dealing with in on OSX.

The first thing that surprised me, is that layers have implicit animations; meaning whenever you change a value, the layer will animate to it using certain defaults. (duration = 0.25, etc.) While it is nice, I am still looking for a way to control it.

When you want to know, when an animation is finished, you need to make a CAAnimation, set the delegate and let it call animationDidStop:

CAAnimationGroup *group = [CAAnimationGroup animation];
group.delegate = self;
group.duration = 0.25;
group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

CABasicAnimation *position = [CABasicAnimation animationWithKeyPath:@"position"];
position.fromValue = fromPointValue;
position.toValue = toPointValue;

CABasicAnimation *opacity = [CABasicAnimation animationWithKeyPath:@"opacity"];
opacity.fromValue = [NSNumber numberWithFloat:1.0];
opacity.toValue = [NSNumber numberWithFloat:0.0];

group.animations = [NSArray arrayWithObjects:position, opacity, nil];

[removeTarget addAnimation:group forKey:@"group"];

While this animates nicely, it still is not quite right. Because the layer basically does not know, that it values are changed in the animation, and therefore, after the animation stopped, the values are reset to the ones BEFORE the animation.

That's the annoying snapback.

To get rid of it, tell the layer the new values, right after you add the animation.

removeTarget.opacity = 0.0;
removeTarget.position = toPointValue;

%nbsp;

Interesting to see, that others seem to go throught the same learning experience.

334Combining Images with UIImage & CGContext – (Offscreen drawing)

In Cocoa NSImage has a lockFocus method, that allows to draw images offscreen and combine them into one.

[img lockFocus];
//...
[img unlockFocus];

On the iPhone, UIImage lacks the lockFocus methods, instead the following:

// Create new offscreen context with desired size
UIGraphicsBeginImageContext(CGSizeMake(64.0f, 64.0f));

// draw img at 0,0 in the context
[img drawAtPoint:CGPointZero];

// draw another at 0,0 in the context, maybe with an alpha value
[another drawAtPoint:CGPointZero];

// ... and other operations

// assign context to UIImage
UIImage *outputImg = UIGraphicsGetImageFromCurrentImageContext();

// end context
UIGraphicsEndImageContext();

47Specifing Values in CALayer

You can not specify a structure field key path using Objective-C 2.0 properties. This will not work:

myLayer.transform.rotation.x=0;

Instead you must use setValue:forKeyPath: or valueForKeyPath: as shown below:

[myLayer setValue:[NSNumber numberWithInt:0] forKeyPath:@"transform.rotation.x"];

brrrrrr.

- (id)valueForKey:(NSString *)key

  • (void)setValue:(id)value forKey:(NSString *)key

... NSKeyValueCoding Protocol Reference