I have a "Cube" class, and it has a -rotate method in it. The method sets the snap in the lower left corner, and then rotates the cube 90 degrees. After that, another method is called that causes the cube to rotate -90 degrees. This is done with an indication of the stop selector. Btw: This has no special purpose. Just learn!
-rotate raises a touch event. But now that the cube object is still rotating and, say, currently it is 33.943 ..., the user can make another touch event before this animation ends.
This touch event will then immediately call the -rotate method again. It happens that the transformations overlap, and the image of the cube is stretched and deformed completely.
So, before starting a new animation, the current animation should stop.
UPDATE
I call this before starting the animation:
- (void)resetAnimation {
self.layer.transform = CATransform3DIdentity;
[Cube setAnimationDelegate:nil];
[Cube setAnimationDidStopSelector:NULL];
}
In addition, I set [Cube setAnimationBeginsFromCurrentState: YES]; where I start the animation block.
So, when the animation is turned on from outside, it will look like this: (Note that on the screen there are 5 objects of this class that can be kicked for animation)
- (void)kickAnimation {
self.layer.transform = CATransform3DIdentity;
currentDegrees = 90;
NSString *animID = [NSString stringWithFormat:@"cube_%i",self.datasetID];
if (currentDegrees > 0) {
[self rotateRight:animID finished:0 context:self];
} else if (currentDegrees < 0) {
[self rotateLeft:animID finished:0 context:self];
}
}
- (void)rotateRight:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
[self rotateByDegrees:currentDegrees animationID:animationID];
}
- (void)rotateByDegrees:(CGFloat)degrees animationID:(NSString *)animationID {
[Cube beginAnimations:animationID context:self];
[Cube setAnimationDelegate:self];
[Cube setAnimationDidStopSelector:@selector(rotateBack:finished:context:)];
[Cube setAnimationDuration:2.1f];
[Cube setAnimationBeginsFromCurrentState:YES];
CATransform3D rotatedTransform = self.layer.transform;
rotatedTransform = CATransform3DRotate(rotatedTransform, degrees * M_PI / 180.0, 0.0f, 0.0f, 1.0f);
self.layer.transform = rotatedTransform;
[UIView commitAnimations];
}
- (void)rotateBack:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
currentDegrees *= -1;
[Cube beginAnimations:animationID context:self];
self.layer.transform = CATransform3DIdentity;
[Cube setAnimationDelegate:nil];
[Cube setAnimationDidStopSelector:NULL];
[Cube setAnimationDuration:2.1f];
[Cube setAnimationBeginsFromCurrentState:YES];
CATransform3D rotatedTransform = self.layer.transform;
rotatedTransform = CATransform3DRotate(rotatedTransform, currentDegrees * M_PI / 180.0, 0.0f, 0.0f, 1.0f);
self.layer.transform = rotatedTransform;
currentDegrees = 0;
[UIView commitAnimations];
}
Now it seems to be almost working. The cube no longer warps if the kickoffs animation overlaps. But one thing is wrong: if a new βhitβ appears and the cube is currently spinning back, it should immediately start spinning to the right. But it happens that he first spins back, and then recognizes a βblowβ, which looks rather strange;)