small medium large xlarge

Wedding photobooth_pragsmall
10 Aug 2009, 15:12
Tony Arnold (11 posts)

I’m having a little trouble - I’ve gone to a bit of effort to bind all of the properties of my CALayer, but now that that is done I realise I can’t use @[CATransaction begin];@ … to set the duration of the animation.

What’s the best way to do this? I’ve tried adding the animations using @addAnimation: forKey:@, but that didn’t work.

11 Aug 2009, 11:16
Christoph Ludwig (13 posts)

What exactly is the issue you face with @[CATransaction setAnimationDuration:requestedDuration]@ ? Maybe if you post some code then someone can help you.

For debugging purposes I have recently used it to make a set of animations last 10 seconds, that worked well. (I don’t like that CATransaction is under-documented IMO. For instance, the documentation fails to explain which objects the transaction mechanism holds on to and where you need to use synchronization mechanisms. But how you set the animation documentation with CATransaction seems clear.)

Wedding photobooth_pragsmall
11 Aug 2009, 17:56
Tony Arnold (11 posts)

Hi Christoph, there’s not really much code to post to be honest. I’ve bound my Core Animation layer properties to my model objects like so:

[aLayer bind:@"contents" toObject:aScreen withKeyPath:@"desktopCGImage" options:nil];

Which means that I’m not manually affecting changes to the properties of my layers (and thus can’t use CATransaction blocks around anything).

I’m wondering if I can subclass CALayer to return a default duration of a certain period?

11 Aug 2009, 18:40
Christoph Ludwig (13 posts)

Hi Tony,

now I understand your problem.

I don’t consider myself an expert on Core Animation and since I never developed with Cocoa, only on the iPhone, I have no experience with the Cocoa key value bindings either. The following ideas come to my mind:

  • What if you define your own actions for the property changes? Does it work if you put BasicAnimations with the respective keypaths and suitable durations in the actions dictionary?
  • If you prefer to subclass CALayer, then you could override animatable properties’ setters such that they put the call @[super setXYZ]@ inside a CATransaction with a suitable duration. You need to be aware that then all property changes happen in different transactions - that may not be what you want.
  • Finally, you could place a proxy object between your model object and the layer (and bind the model to the proxy). That would work for any type of layer and you’d probably have more leeway compared to subclassing CALayer.

Someone with more experience in development for the Mac platform can probably tell you a much better way to approach this…



Wedding photobooth_pragsmall
12 Aug 2009, 23:06
Tony Arnold (11 posts)

Thanks for the advice Christoph. I did try adding my own actions, but they seem to be ignored - I need to go back and make sure I am doing that correctly.

I’d really prefer not to have to use proxy objects - it seems a bit “dirty” - but it would definitely work as advertised.

Wedding photobooth_pragsmall
13 Aug 2009, 15:34
Tony Arnold (11 posts)

OK, so here’s how I made it work - just create a subclass of CALayer and use it any place you need overridden durations. Make sure you include the following method:

+ (id<CAAction>)defaultActionForKey:(NSString *)event {
   if ([event isEqualToString:@"contents"]) {
		CATransition *basicAnimation = [CATransition animation];
		basicAnimation.type = kCATransitionFade;
		basicAnimation.duration = [[NSUserDefaults standardUserDefaults] floatForKey:@"DefaultAnimationSpeed"];
		return basicAnimation;
	} else {
		return nil;

Just add entries for the keys you want, and away it goes :)

You must be logged in to comment