Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why won't a CATransition work if it's added to the subview's layer directly after the subview is added?

For some reason, a CATransition won't animate if the animation is added to the subview's layer directly after the subview is added:

transitionView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[transitionView setBackgroundColor:[UIColor redColor]];
[[self contentView] addSubview:transitionView];

CATransition *animation = [CATransition animation];
[animation setDelegate:self];
[animation setType:@"cube"];
[animation setDuration:1.0];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
[animation setSubtype:@"fromRight"];

[[transitionView layer] addAnimation:animation forKey:nil];

But if the animation is added after a slight delay:

transitionView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[transitionView setBackgroundColor:[UIColor redColor]];
[[self contentView] addSubview:transitionView];

CATransition *animation = [CATransition animation];
[animation setDelegate:self];
[animation setType:@"cube"];
[animation setDuration:1.0];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
[animation setSubtype:@"fromRight"];

[self performSelector:@selector(animate) withObject:nil afterDelay:0.00001];

-

- (void)animate
{
    CATransition *animation = [CATransition animation];
    [animation setDelegate:self];
    [animation setType:@"cube"];
    [animation setDuration:1.0];
    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
    [animation setSubtype:@"fromRight"];

    [[transitionView layer] addAnimation:animation forKey:nil];
}

The transition will work as expected. Is there any reason for this?

like image 984
ProtoSphere Avatar asked Mar 04 '12 04:03

ProtoSphere


1 Answers

I've seen this behavior too. I think it's because the layer is in the “model” layer hierarchy that you can access, but it hasn't yet been added to the “real” data structures that represent what's actually on the screen.

Anyway, you can work around it by using [CATransaction flush] like this:

transitionView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[transitionView setBackgroundColor:[UIColor redColor]];
[[self contentView] addSubview:transitionView];

// Synchronize the implementation details with my changes so far.
[CATransaction flush];

CATransition *animation = [CATransition animation];
[animation setDelegate:self];
[animation setType:@"cube"];
[animation setDuration:1.0];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
[animation setSubtype:@"fromRight"];

[[transitionView layer] addAnimation:animation forKey:nil];
like image 102
rob mayoff Avatar answered Sep 26 '22 14:09

rob mayoff