将逆CATransform3D应用于已经转换的CALayer的子层

时间:2011-11-09 16:43:21

标签: iphone objective-c ios catransform3d homogenous-transformation

我正在使用CATransform3D转换将伪3D透视效果应用于视图。

我正在使用iPhone 4中的陀螺仪来控制变换的参数。

我正在转换的视图有一些子视图:

View with subviews

结果是这样的:

3D transform in action

我的下一个任务是阻止子视图在主视图转换时被转换,或者应用逆转换以使子视图不受影响。

我的目标是让每个子视图与超视图垂直,给人一种他们“站立”的印象。

我用于转换的代码:

- (void)update:(NSTimer *)timer
{
    roll = [[[_manager deviceMotion] attitude] roll];
    pitch = [[[_manager deviceMotion] attitude] pitch];
    yaw = [[[_manager deviceMotion] attitude] yaw];

    CALayer *layer = [self.view layer];
    CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
    rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, -90 * M_PI / 180.0f, 0.0f, 0.0f, 1.0f); // make landscape again  
    rotationAndPerspectiveTransform.m34 = 1.0 / -500; // apply the perspective
    rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, roll, 1.0f, 0.0f, 0.0f);
    rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, yaw, 0.0f, 0.0f, 1.0f);
    [layer setTransform:rotationAndPerspectiveTransform];       
}

我试图通过对Y轴周围的子视图应用90度透视旋转来尝试反转变换:

for (UIView *subview in [self.view subviews])
{
    CALayer *sublayer = [subview layer];
//CATransform3D inverseTransformation = [sublayer transform];
CATransform3D inverseTransformation = CATransform3DIdentity;
rotationAndPerspectiveTransform.m34 = 1.0 / -500; // apply perspective
inverseTransformation = CATransform3DRotate(inverseTransformation, 90 * M_PI / 180.0f, 0.0f, 1.0f, 0.0f);
[sublayer setTransform:inverseTransformation];
}

但所有这一切成功的做法都是让子视图消失。如果我尝试使用[sublayer transform]图层中的现有变换并对其应用3d旋转,则子视图会闪烁,但不会旋转。

我对Matrix数学的了解不是很好,所以我不知道这是不是正确的方法。

如何让子视图与超级视图垂直?

1 个答案:

答案 0 :(得分:1)

我建议不要尝试计算每个变换工作的基本方法。此外,对于每个小子视图而不是更高级别的UIView对象,使用CALayers会更容易。构建3D模型和转换整个模型的基本方法应该对您更有效。

从主图层开始,为每个小方块添加一个子图层,将这些子图层转换为位置,然后您的问题中列出的update:方法可以在不修改的情况下转换所有内容。 John Blackburn has a nice little tutorial应该有很大的帮助。