Im making app for mac. I have 5 cards in a row and on the click of a button all of the cards should flip sequentially (after the flip of the first card should come the flip of the second). The problem im having is the following
When I click the animate button and the cards should flip from back to front (color to number) everything works great. They animate perfectly one after the other with a flip rotation round the Y axis.
But when I click the animate button and the cards should go the other way around (number to color) here is what happens: All of the cards replace their initial layer with the back layer without any animation and all at once.
After that every card one by one (sequentially) change into the correct front layer and animate to back layer.
Here is a video of the animation
https://www.youtube.com/watch?v=fznUFR6pHCQ&feature=youtu.be
What do I change so I can get the animation ok.
I initialized the cards like this
flip1= [[PKRGSPFlipAnimationController alloc] initWithParent:firstCardView newFrontImage:[NSImage imageNamed:@"front.png"]];
flip2= [[PKRGSPFlipAnimationController alloc] initWithParent:secondCardView newFrontImage:[NSImage imageNamed:@"front.png"]];
flip3= [[PKRGSPFlipAnimationController alloc] initWithParent:thirdCardView newFrontImage:[NSImage imageNamed:@"front.png"]];
flip4= [[PKRGSPFlipAnimationController alloc] initWithParent:fourthCardView newFrontImage:[NSImage imageNamed:@"front.png"]];
flip5= [[PKRGSPFlipAnimationController alloc] initWithParent:fifthCardView newFrontImage:[NSImage imageNamed:@"front.png"]];
On a click of a button i call this function
[flip1 flip:1];
[flip2 flip:2];
[flip3 flip:3];
[flip4 flip:4];
[flip5 flip:5];
Here is the class of the flips(flip1-5): .m file
define FLIP_TIME 1.0 // Time taken to do the animation.
#define PERSPECTIVE 1000
#define RECT NSMakeRect(0, 0, 134, 198) // Value of the coordiantes of the parent view.
#define DEGREES_TO_RADIANS(angle) (angle * M_PI / 180.0)
#import "PKRGSPFlipAnimationController.h"
@implementation PKRGSPFlipAnimationController
@synthesize cardLayer;
@synthesize frontLayer;
@synthesize backLayer;
@synthesize parentView;
@synthesize isFront;
-(id)initWithParent:(NSView *)newParent newFrontImage:(NSImage *)newFront{
self = [super init];
if (self) {
parentView = newParent;
isFront = false;
cardLayer =[CATransformLayer layer];
[cardLayer setFrame:RECT];
frontLayer = [CALayer layer];
[frontLayer setFrame:RECT];
[frontLayer setZPosition:1.0];
[frontLayer setDoubleSided:NO];
[frontLayer setContents:(id)newFront];
[cardLayer addSublayer:frontLayer];
backLayer = [CALayer layer];
[backLayer setFrame:RECT];
[backLayer setZPosition:2.0];
[backLayer setDoubleSided:NO];
[backLayer setContents:(id)[NSImage imageNamed:@"back.png"]];
[cardLayer addSublayer:backLayer];
[parentView setLayer:[CALayer layer]];
[parentView setWantsLayer:YES];
[parentView.layer addSublayer:cardLayer];
}
return self;
}
- (CAAnimation*) createAnimFrom:(double)frAngl to:(double)toAngl
{
//For the card to rotate on the
// Y axis - @"transform.rotation.y"
// X axis - @"transform.rotation.x"
NSString* rotationAxis = @"transform.rotation.y";
CABasicAnimation* ba = [CABasicAnimation animationWithKeyPath:rotationAxis];
ba.fromValue = [NSNumber numberWithFloat:frAngl];
ba.toValue = [NSNumber numberWithFloat:toAngl];
CABasicAnimation *shrinkAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
shrinkAnimation.toValue = [NSNumber numberWithFloat:0.7f];
shrinkAnimation.duration = FLIP_TIME*0.5;
shrinkAnimation.autoreverses = YES;
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
animationGroup.animations = [NSArray arrayWithObjects:ba, shrinkAnimation, nil];
animationGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animationGroup.duration = FLIP_TIME;
animationGroup.fillMode = kCAFillModeForwards;
animationGroup.removedOnCompletion = NO;
return animationGroup;
}
-(void) flip: (int) beginTime
{
CALayer * currLayer;
CALayer * nextLayer;
if(isFront){
currLayer=frontLayer;
nextLayer=backLayer;
}
else{
currLayer=backLayer;
nextLayer=frontLayer;
}
NSLog(@"%hhd", isFront);
isFront=!isFront;
[CATransaction begin];
CAAnimation* anim1 = [self createAnimFrom:0.0 to:M_PI];
anim1.duration = FLIP_TIME;
anim1.beginTime = CACurrentMediaTime()+beginTime;
CAAnimation* anim2 = [self createAnimFrom:-M_PI to:0.0];
anim2.duration = FLIP_TIME;
anim2.beginTime = CACurrentMediaTime()+beginTime;
[CATransaction commit];
//add perspective
CATransform3D mt = CATransform3DIdentity;
mt.m34 = 1.0/(double)PERSPECTIVE;
currLayer.transform = mt;
nextLayer.transform = mt;
NSPoint ap = {0.5,0.5};
currLayer.anchorPoint = ap;
nextLayer.anchorPoint = ap;
[CATransaction begin];
[currLayer addAnimation:anim1 forKey:@"flip"];
[nextLayer addAnimation:anim2 forKey:@"flip"];
[CATransaction commit];
}
@end
.h file
#import <Cocoa/Cocoa.h>
#import <QuartzCore/QuartzCore.h>
@interface PKRGSPFlipAnimationController : NSObject
-(id)initWithParent:(NSView *)newParent newFrontImage:(NSImage *)newFront;
- (void) flip: (int) beginTime;
@property (nonatomic, strong) NSView* parentView;
@property (nonatomic, strong) CATransformLayer * cardLayer;
@property (nonatomic, strong) CALayer *frontLayer; // Front side (Number side) of the card.
@property (nonatomic, strong) CALayer *backLayer; // Back side (Blank side) of the card.
@property (nonatomic) BOOL isFront; // Boolean value for the card to check if it is turned.
@end
I added an on Animation stop and initialized it again. That fixed the problem