CATransaction: problems when implementing a page flipping animation

501 Views Asked by At

I'm trying to implement a page flipping animation - which works, when the user doesn't navigate too fast through the pages.

My code looks like this:

[CATransaction begin];
[CATransaction setAnimationDuration:duration];
[CATransaction setCompletionBlock:^{
    if (pageDifference == 1 && setDelegate) {
        [self cleanupFlip];
        self.animationInProgress = NO;
    }
}];
flipAnimationLayer.transform = endTransform;
[CATransaction commit];

The endTransform is a CATransform3DIdentity, which, as I said, works fine. In my cleanupFlip I'm preparing the screenshot for the next page, which enables me to perform the page flipping animation. And the screenshot I'm makiing seems to be the problem; as soon as the user clicks to fast through the pages, the animation doesn't happen but the pages just change - without page flipping animation. I got an improvement through setting a flag animationInProgress which avoids starting the next animation before the old finishes.

What I don't get: I'm expecting to work this fine, as I'm setting the animationInProgress flag at the very end of the animation, so everything should be prepared for the next run - but it isn't...

On the simulator I can click faster than on the device - there I have to wait for a second until I can start the next page turn.

Without making the screenshot (e.g., just using an empty image), everything works as expected. It seems as if it's a problem if the cleanupFlip takes some time.

Any ideas how I could make this work?

Thanks a lot!

1

There are 1 best solutions below

0
On

The most likely cause of this behavior, is that the user is faster than the animation. That is, the second [CATransaction begin] is started before the first animation has finished, and therefore before your setCompletionBlock is executed. I am not sure what the exact order is, but setting some NSLog statements in your code should make it clear.

One solution might be to create the image not in the setCompletionBlock, but right before the begin. Or, if creation of the image takes a lot of time, prepare it for the next page right after the commit of the first transaction.

Putting a [CATransaction flush] right before the [CATransaction begin] has also helped me before in these type of situations.