我尝试创建一个CATransform3D,但是错了。以下代码使用键值执行我想要的:
[_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"];
以下是我尝试将其设置为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);
如何使用键路径创建匹配变换?
答案 0 :(得分:6)
看看你的两个截图,并假设你想要一个旋转的立方体效果,并且两个截图是在动画中略有不同的时间拍摄的,看起来顶部的截图有透视效果,而底部截图有不。
修复此问题很简单,只需编辑变换的.m34值,通常为1/500即可。这篇here有很好的写作。
完成后,您需要在轮换之前应用转换步骤,如下所示:
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);
我做过类似的事情,但是使用容器视图控制器从一个转换到下一个。在评论你的代码时,我认为我使用了z锚点,但事实证明我没有。这是我用来从一个视图控制器转换到另一个视图控制器的代码,就像你在旋转一个立方体一样。它可能是有意义的。这只是较大方法的摘录,希望我没有错过任何重要的东西。
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;
}];
为了试验3D变换,我创建了一个小的演示应用程序,允许您构建一堆变换并查看效果。它在GitHub上提供,并引入了here。