我有一系列UIImages,我需要用它来模拟深度。我无法使用缩放,因为我需要能够旋转父视图,并且图像应该看起来像是在彼此前面明显堆叠,而不是在同一平面上。
我创建了一个基于ViewController的新项目并将其放在viewDidLoad中(以及附加的三个120x120像素图像,名为1.png,2.png和3.png):
- (void)viewDidLoad {
// display image 3
UIImageView *three = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"3.png"]];
three.center = CGPointMake(160 + 60, 240 - 60);
[self.view addSubview:three];
// rotate image 3 around the z axis
// THIS IS INCORRECT
CATransform3D theTransform = three.layer.transform;
theTransform.m34 = 1.0 / -1000;
three.layer.transform = theTransform;
// display image 2
UIImageView *two = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"2.png"]];
two.center = CGPointMake(160, 240);
[self.view addSubview:two];
// display image 1
UIImageView *one = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"1.png"]];
one.center = CGPointMake(160 - 60, 240 + 60);
[self.view addSubview:one];
// rotate image 3 around the z axis
// THIS IS INCORRECT
theTransform = one.layer.transform;
theTransform.m34 = 1.0 / 1000;
one.layer.transform = theTransform;
// release the images
[one release];
[two release];
[three release];
// rotate the parent view around the y axis
theTransform = self.view.layer.transform;
theTransform.m14 = 1.0 / -500;
self.view.layer.transform = theTransform;
[super viewDidLoad];
}
我有非常具体的原因,为什么我没有使用EAGLView以及为什么我不将图像作为CALayers加载(即为什么我为每个使用UIImageViews)。这只是一个快速演示,我可以使用它来准确地解决我在父应用程序中需要的内容。
是否有一些矩阵方式可以沿z轴平移这些2d图像,所以它们看起来就像我想要代表的那样?我已经阅读了其他StackOverflow文章以及维基百科的参考文献,并且没有找到我正在寻找的东西 - 尽管我可能不一定使用正确的术语来解决我想要做的事情。
答案 0 :(得分:7)
为了叠加视图并让它们应用透视图,您需要先将它们放在不同的Z位置,然后将透视效果应用于包含图层。
我相信以下代码会做到这一点,但我没有测试过它(我做过类似于纯CALayers的事情,所以一般原则是正确的):
- (void)viewDidLoad {
UIImageView *three = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"3.png"]];
three.center = CGPointMake(160 + 60, 240 - 60);
[self.view addSubview:three];
three.layer.zPosition = -100;
UIImageView *two = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"2.png"]];
two.center = CGPointMake(160, 240);
[self.view addSubview:two];
two.layer.zPosition = 0;
UIImageView *one = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"1.png"]];
one.center = CGPointMake(160 - 60, 240 + 60);
[self.view addSubview:one];
one.layer.zPosition = 100;
// release the images
[one release];
[two release];
[three release];
CATransform3D theTransform = self.view.layer.sublayerTransform;
theTransform.m34 = 1.0 / -500;
self.view.layer.sublayerTransform = theTransform;
[super viewDidLoad];
}
在您的代码中,您只在每个视图的图层上设置CATransform3D的每个部分(这就是CATransform3D矩阵的m34组件所做的)。你实际上并没有在Z平面上移动它们。您可以使用转换,但我发现CALayers的zPosition
属性提供了一种更简洁的方法来定位三维图层。
一旦您将图层相对于彼此放置(负值远离用户的视点),您需要将透视效果应用于主视图中托管的所有图层。为此,我发现设置托管视图图层的sublayerTransform
是必要的,以便将透视图正确应用于所有托管图层。
如果您想旋转一系列图像,请在主要托管视图图层的sublayerTransform上使用CATransform3DRotate()
。
对于执行CALayers三维操作的示例应用程序,如果应用了透视图,请在我的文章here的第二次更新中查看我链接到的项目。
答案 1 :(得分:2)
我终于通过使用CATransform3DMakeTranslation解决了这个问题,这似乎是在z轴上向上或向下移动图层的唯一方法:
UIImageView *three = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"3.png"]];
three.layer.transform = CATransform3DMakeTranslation(0.0f, 0.0f, 20.0f);
three.center = CGPointMake(160 + 60, 240 - 60);
[self.view addSubview:three];
(我还在U轴上移动了一个-20.0f像素的UIImageView。这最终产生了我想要的效果。)