iphone - 如何使用核心动画堆叠图像来模拟深度?

标签 iphone core-animation

我有一系列 UIImages,我需要用它们来模拟深度。我无法使用缩放,因为我需要能够旋转父 View ,并且图像应该看起来像是明显堆叠在彼此前面,而不是在同一平面上。

我创建了一个新的基于 ViewController 的项目,并将其放入 viewDidLoad 中(并附加了三个名为 1.png、2.png 和 3.png 的 120x120 像素图像):

- (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 文章以及 Wikipedia 引用资料,但没有找到我正在寻找的内容 - 尽管我可能不一定使用正确的术语来实现我想要做的事情。

最佳答案

为了堆叠 View 并应用透视效果,您需要首先将它们放置在不同的 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];
}

在您的代码中,您仅在每个 View 的图层上设置 CATransform3D 的透视部分(这就是 CATransform3D 矩阵的 m34 组件的作用)。您实际上并没有在 Z 平面上移动它们。您可以为此使用变换,但我发现 CALayers 的 zPosition 属性提供了一种更清晰的方式来定位 3-D 图层。

将图层相对放置后(负值远离用户的视角),您需要对主视图中托管的所有图层应用透视效果。为此,我发现设置托管 View 图层的 sublayerTransform 是必要的,以便将透视正确应用于所有托管图层。

如果您希望旋转一系列图像,请在主托管 View 图层的 sublayerTransform 上使用 CATransform3DRotate()

对于对 CALayers 进行 3D 操作并应用透视图的示例应用程序,请查看我在文章 here 的第二次更新中链接到的项目。 .

关于iphone - 如何使用核心动画堆叠图像来模拟深度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2834985/

相关文章:

iphone - 如何将文件从 S3 下载到 iPhone 应用程序?

iphone - 将 iPhone 日历与您的应用程序同步

objective-c - 如何在 Mac 上与 layer-backed views 交互

ios - UIPageViewController 的 viewController subview 动画转换

ios - 红框移动到核心动画中 UIImage View 的位置

iphone - Objective-c/IOS : Reversing the bytes in NSMutabledata

iphone - 如何将 UISegmentedControl 合并到 UITabBarController 中?

objective-c - cocoa 层支持的 View : When can I NOT enable layer-backing on a window content view?

ios - 使用 PresentViewController 而不是 Storyboard 不会显示单元格数据?

ios - 如何为 UICollectionView 实现放大/缩小动画