Consecutive animations

I'm new to Core Animations, I want to fade out two different layers one after another.I write them in a CATransaction block. I wonder if there is better approach to make such animations.

[CATransaction begin];

[self setupCheckMarkLayer]; //initialize _checkMarkLayer
fadeOutCheckMark.beginTime = [_checkMarkLayer convertTime:CACurrentMediaTime() fromLayer:nil] + 0.5;
_checkMarkLayer.opacity = 0.;

[CATransaction setCompletionBlock:^{
self.userInteractionEnabled = YES;
}];

[CATransaction commit];

• Does [NSNumber numberWithFloat:0.] actually work? – nhgrif Nov 13 '14 at 22:34
• yes,it works :) try it – Pkwies Nov 14 '14 at 9:15

We have some magic numbers. Also, why don't we use modern syntax for our NSNumber objects?

NSNumber *opacityFromValue = @0.3f;
NSNumber *opacityToValue = @0.0f;

CGFloat timeCheckmarkOffset = 0.5;


And now use these variables in place of the magic numbers.

As an added bonus, we'll get slightly better performance by not having to instantiate the opacity values twice each. NSNumber is an immutable object, so it doesn't matter that we pass the same one both times.

• okay I changed those values thank you, do you also have a suggestion for animation block? – Pkwies Nov 14 '14 at 9:19
• I'm not particularly familiar with CoreAnimation. I'll only comment on what I actually know. – nhgrif Nov 15 '14 at 12:53

As an aside, I do want to comment on this line:

[self.delegate finishedLoading];


Consider this, there's nothing that prevents your delegate from delegating multiple objects. Moreover, finishedLoading might be a fairly common method name multiple protocols might like to define.

So, let's presume our class that has this delegate is called MyAnimatingImage, and the protocol is called MyAnimatingImageDelegate. Rather than looking like this:

@protocol MyAnimatingImageDelegate

@end


We will be better off with a protocol that looks like this:

@protocol MyAnimatingImageDelegate

@end


And when we call the method, we do so as such:

[self.delegate animatingImageDidFinishLoading:self];


We pass the delegate a reference to self. Yes, in most cases the delegate will already have a reference to us. And in a lot of cases, the delegate may not be using multiple objects of this type, so it'll always know what finishedLoading is talking about... but consider this case:

- (void)viewDidLoad {
self.object1 = [MyAnimatingImage animatingImage];
self.object2 = [MyAnimatingImage animatingImage];


Now, when object1 finishes loading and calls finishedLoading without passing a reference to itself, how does our delegate know whether object1 or object2 is finished loading? It can't. It might assume that object1 is always finished loading first, but that's not always going to be the case, particularly if there's anything asynchronous about the loading.
• I also created a __block variable for self. __block id< MyAnimatingImage > delegate= self.delegate; – Pkwies Nov 15 '14 at 15:22