How do I stack images to simulate depth using Core Animation?

前端 未结 2 1792
忘掉有多难
忘掉有多难 2020-12-08 08:43

I have a series of UIImages with which I need to simulate depth. I can\'t use scaling because I need to be able to rotate the parent view, and the images should look like t

相关标签:
2条回答
  • 2020-12-08 09:12

    In order to stack your views, and have them have perspective applied, you will need to first place them at different Z positions, then apply a perspective effect to the containing layer.

    I believe the following code will do this, but I've not tested it (I've done something similar with pure CALayers, so the general principles are correct):

    - (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];
    }
    

    In your code, you are only setting the perpective portion of the CATransform3D on each view's layer (that's what the m34 component of the CATransform3D matrix does). You are not actually displacing them in the Z plane. You could use a transform for this, but I find that the zPosition property of your CALayers provides a cleaner way to locate the layers in 3-D.

    Once you've placed the layers relative to one another (with negative values going away from the viewpoint of the user), you need to apply a perspective effect to all layers hosted within your main view. For this, I find that setting the sublayerTransform of the hosting view's layer is necessary in order for the perspective to be applied correctly to all hosted layers.

    If you wish to rotate the series of images, use CATransform3DRotate() on the sublayerTransform of the main hosting view's layer.

    For an example application that does 3-D manipulation of CALayers, with perspective applied to them, check out the project I link to in the second update of my article here.

    0 讨论(0)
  • 2020-12-08 09:15

    I finally solved this by using CATransform3DMakeTranslation, which seems to be the only way to move a layer up or down the z-axis:

    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];
    

    (I also moved UIImageView one -20.0f pixels on the z-axis. That finally gave the effect I was looking for.)

    0 讨论(0)
提交回复
热议问题