Reputation: 4552
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];
}];
}
Upvotes: 0
Views: 135
Reputation: 77631
It is flipped horizontally because that's what you've just done. You've just flipped the view 180degrees.
The way to get around this is to do the animation in stages.
It will look like the view has rotated 180 degrees but in fact it has not changed at all at the end of the animation. It just looks like it changed.
Upvotes: 3