Looking at your two screenshots and assuming that you are going to use the rotating effect of the cube, and two screenshots are taken several times in the animation, it looks like the top has a perspective, and the bottom does not.
The fix is a simple matter of editing the value of the .m34 conversion, usually a small value, such as 1/500. There is an excellent record of this here .
Having done this, you need to apply the translation steps before rotation, for example:
CATransform3D subLayerTransform = CATransform3DMakeTranslation(0, 0, 0); subLayerTransform.m34 = -0.000555; subLayerTransform = CATransform3DTranslate(subLayerTransform, _currentMetrics.translationPointsX, 0, _currentMetrics.translationPointsZ); subLayerTransform = CATransform3DRotate(subLayerTransform, _currentMetrics.radians, 0, 1, 0);
I did something similar, but used a container controller to go from one to another. Commenting on my code, I thought I used the z anchor point, but it turned out that I did not. Here is the code that I use to go from one view controller to another, as if you were rotating a cube. This may be of interest. This is just an excerpt from a larger method, I hope I have not missed anything vital.
CGRect newFrame = self.containerView.bounds; UIView *outgoingView = _currentViewController.view; UIView *incomingView = currentViewController.view; incomingView.frame = newFrame; [CATransaction begin]; [CATransaction setDisableActions:YES]; CATransform3D parent = CATransform3DIdentity; parent.m34 = -0.003; self.containerView.layer.sublayerTransform = parent; BOOL rightToLeft = (_currentViewController == [self.viewControllers itemBefore:currentViewController]); CGFloat inTranslateX = incomingView.bounds.size.width; CGFloat inRotation = M_PI_2; CGFloat inAnchorX = 0.0; if (!rightToLeft) { inTranslateX = -inTranslateX; inRotation = -inRotation; inAnchorX = 1.0; } CATransform3D inT = CATransform3DMakeTranslation(inTranslateX, 0.0, 0.0); inT = CATransform3DRotate(inT, inRotation, 0.0, 1.0, 0.0); CGRect previousFrame = incomingView.frame; incomingView.layer.anchorPoint = CGPointMake(inAnchorX, 0.5); incomingView.frame = previousFrame; incomingView.layer.transform = inT; incomingView.hidden = NO; CGFloat outTranslateX = -outgoingView.bounds.size.width; CGFloat outRotation = -M_PI_2; CGFloat outAnchorX = 1.0; if (!rightToLeft) { outTranslateX = -outTranslateX; outRotation = -outRotation; outAnchorX = 0.0; } CATransform3D outT = CATransform3DMakeTranslation(outTranslateX, 0.0, 0.0); outT = CATransform3DRotate(outT, outRotation, 0.0, 0.5, 0.0); CGRect outgoingFrame = outgoingView.frame; outgoingView.layer.anchorPoint = CGPointMake(outAnchorX, 0.5); outgoingView.frame = outgoingFrame; [CATransaction commit]; [self transitionFromViewController:_currentViewController toViewController:currentViewController duration:0.4 options:UIViewAnimationCurveEaseInOut animations:^{ outgoingView.layer.transform = outT; incomingView.layer.transform = CATransform3DIdentity; } completion:^(BOOL finished) { _currentViewController = currentViewController; outgoingView.layer.transform = CATransform3DIdentity; self.imageView.image = currentViewController.tabBarItem.image; self.viewSelector.userInteractionEnabled = YES; }];
For experimenting with 3D transforms, I created a small demo application that allows you to create a stack of transformations and see effects. It is available on GitHub and introduced here .