How to create a CATransform3D mapping done using setValue: forKey:

I tried to create CATransform3D but was mistaken. The following code does what I want using the key values:

[_transitionLayer setValue:[NSNumber numberWithFloat:metrics.translationPointsX] forKeyPath:@"sublayerTransform.translation.x"]; [_transitionLayer setValue:[NSNumber numberWithFloat:metrics.radians] forKeyPath:@"sublayerTransform.rotation.y"]; [_transitionLayer setValue:[NSNumber numberWithFloat:metrics.translationPointsZ] forKeyPath:@"sublayerTransform.translation.z"]; 

right

And this is how I tried to configure it using CATransform3D:

 subLayerTransform.m34 = -0.000555; CATransform3D subLayerTransform = CATransform3DMakeTranslation(0, 0, 0); subLayerTransform = CATransform3DTranslate(subLayerTransform, metrics.translationPointsX, 0, 0); subLayerTransform = CATransform3DRotate(subLayerTransform, metrics.radians, 0, 1, 0); subLayerTransform = CATransform3DTranslate(subLayerTransform, 0, 0, metrics.translationPointsZ); 

wrong

How can I create a suitable conversion for one using keys?

+4
source share
1 answer

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 .

+6
source

Source: https://habr.com/ru/post/1481859/


All Articles