如何使用setValue创建与另一个匹配的CATransform3D:forKey:

时间:2013-05-21 01:29:34

标签: ios objective-c core-animation catransform3d

我尝试创建一个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"];

right

以下是我尝试将其设置为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

如何使用键路径创建匹配变换?

1 个答案:

答案 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