SagarU
SagarU

Reputation: 426

UIImageView perspective tilt

What I want: https://i.sstatic.net/K1pYo.jpg

What I have achieved: https://i.sstatic.net/SV5Pi.jpg

Below is the function I am using:

- (void) showViewWithImageFromAsset: (PHAsset *) asset
 {
     UIView *imageContainer = [[UIView alloc] initWithFrame:CGRectMake(25, 320, 400, 400)];
     [imageContainer setBackgroundColor:[UIColor whiteColor]];
     UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 250, 200)];


     CGFloat shadowRadius = 0.0;
     CGFloat width = imageView.frame.size.width;
     CGFloat height = imageView.frame.size.height; // Get width and height of the view

// Plot the path
UIBezierPath *shadowPath = [[UIBezierPath alloc] init];
[shadowPath moveToPoint:CGPointMake(width, 0)];
[shadowPath addLineToPoint:CGPointMake((width)+10, 10)];
[shadowPath addLineToPoint:CGPointMake((width)+10, height-10)];
[shadowPath addLineToPoint:CGPointMake(width, height)];

imageView.layer.shadowColor = UIColor.blackColor.CGColor;
imageView.layer.shadowPath = shadowPath.CGPath;
imageView.layer.shadowRadius = shadowRadius;
imageView.layer.shadowOffset = CGSizeZero;
imageView.layer.shadowOpacity = 1.0;

PHImageRequestOptions *requestOptions = [[PHImageRequestOptions alloc] init];
requestOptions.resizeMode   = PHImageRequestOptionsResizeModeExact;
requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
requestOptions.synchronous = YES;

PHImageManager *manager = [PHImageManager defaultManager];

// assets contains PHAsset objects.
__block UIImage *ima;

[manager requestImageForAsset:asset
                   targetSize:PHImageManagerMaximumSize
                  contentMode:PHImageContentModeDefault
                      options:requestOptions
                resultHandler:^void(UIImage *image, NSDictionary *info) {
                    ima = image;
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [imageView setImage:ima];

                        CATransform3D t = CATransform3DIdentity;
                        t.m34 = .005;
                        imageContainer.layer.sublayerTransform = t;
                        imageView.layer.transform = CATransform3DMakeRotation(-10,0,1,0);
                        [imageContainer addSubview:imageView];
                        //[imageContainer addSubview:imageSideView];
                        [self.view addSubview:imageContainer];
                        [self.view bringSubviewToFront:imageView];
                    });

                }];

}

As you can see, I have achieved the desired effect albeit with an inverted (or mirrored) image. I do not intend to use any third party framework/library to achieve this since I know it is possible by modifying the existing code.

While I can change the y value in CATransform3DMakeRotation(-10,0,1,0), from 1 to 0 to get the correct image orientation, that will aslo change the perspective to this https://i.sstatic.net/Bz24T.jpg

I need something to get the right image without changing the perspective. Any help is greatly appreciated.

Upvotes: 0

Views: 118

Answers (1)

rmaddy
rmaddy

Reputation: 318794

The biggest issue is that the first argument to CATransform3DMakeRotation needs to be radians, not degrees.

imageView.layer.transform = CATransform3DMakeRotation(-10 * M_PI / 180.0, 0, 1, 0);

Then you need to change the x of the shadowPath:

[shadowPath moveToPoint:CGPointMake(0, 0)];
[shadowPath addLineToPoint:CGPointMake(-10, 10)];
[shadowPath addLineToPoint:CGPointMake(-10, height-10)];
[shadowPath addLineToPoint:CGPointMake(0, height)];

This gives the desired result.

Upvotes: 2

Related Questions