I'm trying to transition from one view to another. I know there's the "[UIView transitionWithView..." but I'm going to add more complex things to the animation layer and need to write the code myself.
The code below works, but has three problems:
When the backside view appears, it's flipped horizontal.
After the animation has completed, I add the backside view and remove the frontside. During the animation, both view becomes a little bigger due to the perspective (m34), so when the completionBlock adds the new view to the screen, there's an ugly snap back to it's original size.
I need to delay the CATransaction with a block (runBlockAfterDelay). If I don't have the block, the animation will not run.
Thanks in advance
For extra credit :), Is it possible to have the code in a class method? e.g + (void)flippFromView...
- (void)flipFromView:(UIView *)fromView toView:(UIView *)toView spaceBetweenLayers: (CGFloat)spaceBetweenLayers duration:(CGFloat)duration delay:(CGFloat)delay (void))block
{
// Move flipp view back, behind front view
toView.layer.transform = CATransform3DMakeTranslation(0.0, 0.0, -spaceBetweenLayers);;
// Layer that will handle the animation
CALayer *rootLayer = [CALayer layer];
rootLayer.frame = self.frame;
rootLayer.position = fromView.layer.position;
[self.layer addSublayer:rootLayer];
//Transform Layer
CATransformLayer *transformLayer = [CATransformLayer layer];
[transformLayer addSublayer:fromView.layer];
[transformLayer addSublayer:toView.layer];
[rootLayer addSublayer:transformLayer];
[self runBlockAfterDelay:delay block:^{
[CATransaction begin];
[CATransaction setValue:@(duration) forKey:kCATransactionAnimationDuration];
// Completion block
[CATransaction setCompletionBlock:^{
// App crashes with EXC_BAD_ACCESS if we don't move the layer back to the super layer before removing the rootLayer
[self.layer addSublayer:fromView.layer];
[self.layer addSublayer:toView.layer];
// Add new, and remove old layer
[self addSubview:toView];
[fromView removeFromSuperview];
// Set Z position
fromView.layer.zPosition = -10;
toView.layer.zPosition = 10;
// Clean up
[rootLayer removeFromSuperlayer];
}];
// Flipp
CATransform3D flippTransform = CATransform3DMakeRotation(DegreesToRadians(180), 0, 1, 0);
flippTransform.m34 = 1.0f/500.0f;
rootLayer.sublayerTransform = flippTransform;
[CATransaction commit];
}];
}