Janum Trivedi
Janum Trivedi

Reputation: 1690

Combining a UIView perspective transform with other CATranform3Ds

I'm writing an app such that sprites (subclasses of UIImageView) can be rotated, resized, and panned across the screen using gestures. I also would like to be able to apply a 3D perspective transformation to the sprites.

I have the rotate/resize/pan functionality working correctly, as well as the perspective transform. However, they don't seem to work together correctly. If I rotate an unmodified sprite, then try to skew it, the sprite 'resets' it's rotation, then applies the perspective. The opposite works though; if I skew first, I can apply any 2D transformation after without it resetting.

Here is the code I'm using: (rotate, resize, and pan are done using UIGestureRecognizers, whereas the skew uses a UISlider).

Rotate:

- (void)didRotateSprite:(UIRotationGestureRecognizer *)rotate
{
    CGFloat angle = rotate.rotation;

    CATransform3D transform = CATransform3DIdentity;
    transform = CATransform3DRotate(spriteView.layer.transform, angle, 0, 0, 1);

    spriteView.layer.transform = transform;

    rotate.rotation = 0.0;
}

Resize:

- (void)didPinchSprite:(UIPinchGestureRecognizer *)pinch
{
    CGFloat scale = pinch.scale;

    CATransform3D transform = CATransform3DIdentity;
    transform = CATransform3DScale(spriteView.layer.transform, scale, scale, 1);

    view.layer.transform = transform;

    pinch.scale = 1.0;
}

Perspective:

- (IBAction)perspectiveChanged:(UISlider *)slider
{
    CATransform3D transform = CATransform3DIdentity;
    transform.m34 = 1.0 / -100;
    transform = CATransform3DRotate(transform, (1 - (slider.value * 2)) * M_PI_2, 1, 0, 0);

    spriteView.layer.transform = transform;
}

Thank you!

Upvotes: 4

Views: 947

Answers (1)

Janum Trivedi
Janum Trivedi

Reputation: 1690

Found the answer with a lot of debugging and the help of this question. The trick was to transform the view's perspective using:

spriteView.superview.layer.sublayerTransform = transform;

This recursively applies the transformation to the view's superview and any subviews contained in it. For more information about this, check out the documentation and Apple's Layer Style Properties guide too.

Upvotes: 1

Related Questions