UIView Perspective feature - ios

I've got a view and I would like to scale this view as like below image. How do we achieve this?
Thanks,
Mahesh

You need to rotate your view's layer. Something like this,
CALayer *layer = yourView.layer;
CATransform3D rotationTransform = CATransform3DIdentity;
rotationTransform.m24 = 1.0 / -350;
rotationTransform = CATransform3DRotate(rotationTransform, 60*M_PI/180, 1.0, 0.0, -0.1);
[layer setTransform: rotationTransform];
Check out this guide to understand CALayer's geometry and how it works.

Related

Progress View Flip and Scale

I am trying to flip a UIProgressView 180 in Xcode and I am trying to scale the progress view at the same time. The scaling works great until I add the flip and then the scaling does not work anymore. Any suggestions? Thanks!
[self.secondsPorgressBarTicker setTransform:CGAffineTransformMakeScale(1.0, 10.0)];
[self.secondsPorgressBarTicker setTransform:CGAffineTransformMakeRotation(-M_PI)];
You are setting the transform and then resetting it. If you want to combine transforms, you need to use different CG functions. Remember, order matters with transforms, so use whichever one solves your issue:
CGAffineTransform transform = CGAffineTransformMakeRotation(-M_PI);
transform = CGAffineTransformScale(transform, 1.0, 10.0);
[self.secondsPorgressBarTicker setTransform:transform];
or
CGAffineTransform transform = CGAffineTransformMakeScale(1.0, 10.0);
transform = CGAffineTransformRotate(transform, -M_PI);
[self.secondsPorgressBarTicker setTransform:transform];
You're making a new transform. Modify the existing one:
[self.secondsPorgressBarTicker setTransform:CGAffineTransformMakeScale(1.0, 10.0)];
[self.secondsPorgressBarTicker setTransform:CGAffineTransformRotate(self.secondsPorgressBarTicker, -M_PI)

Changing the CALayer anchor point

Changing the anchor point of a CALayer after a CATransform3dRotate gives weird results. I think the problem is, anchorPoint property is set on the previous state (no transform) of layer not the current state (after transform) of the layer.
Is there a way to change the anchorPoint of a CALayer's current state??
Code for Transform:
CATransform3D transform = CATransform3DIdentity;
transform.m34 = -(1.0/800.0);
videoPlayerView.layer.zPosition = 100;
videoPlayerView.layer.transform = CATransform3DRotate(transform, (30*M_PI)/180, 1.0f, 0.0f, 0.0f);
Code to change the anchor Point
if(videoPlayerView.layer.anchorPoint.x != 0.0)
{
videoPlayerView.layer.anchorPoint = CGPointMake(0.0, 0.5);
videoPlayerView.layer.position = CGPointMake(videoPlayerView.layer.frame.origin.x - videoPlayerView.layer.frame.size.width/2,videoPlayerView.layer.position.y);
}
Basically, I have to rotate the Layer like a book flip. I have already done this without using the 30 degree transofrm, but I want it to look more 3D so applied the 30 degree transform along the x axis. So that it looks like the book is placed on a table.
And in order to rotate, setting the anchor point is necessary. If not, please advice otherwise...
instead of changing anchorPoint use
CATransform3DTranslate(transform, 50.0000f, 0.0000f, 0.0000f);
Translate along X by 50.00 points
Apply 0.40 percent of perspective or you can use the same code you are using right now
rotate the CAlayer using Y .
CATransform3D transform = CATransform3DIdentity;
CATransform3D tmp = CATransform3DIdentity;
transform = CATransform3DRotate(transform, 0.0146f, 0, 1, 0);
transform = CATransform3DTranslate(transform, 50.0000f, 0.0000f, 0.0000f);
tmp = CATransform3DIdentity;
tmp.m34 = 0.0040f;
transform = CATransform3DConcat(transform, tmp);
check the link for more reference.
let me know if it works.

Set a UIView scale transform without effecting other transforms

I have a UIView that I scale down when it is touched and scale back up when the touch is ended or cancelled.
I had been scaling the view like this
Scale down:
CGAffineTransform transform = CGAffineTransformMakeScale(0.95, 0.95);
self.transform = transform;
Scale up:
CGAffineTransform transform = CGAffineTransformMakeScale(1.0, 1.0);
self.transform = transform;
This doesn't preserve any other transform. I know I can use this to preserve the old transforms:
Scale down:
CGAffineTransform transform = CGAffineTransformScale(self.transform, 0.95, 0.95);
self.transform = transform;
Scale up:
CGAffineTransform transform = CGAffineTransformScale(self.transform, 1.0, 1.0);
self.transform = transform;
But of course here the scale up has no effect- plus there is potential to have cumulative scale down animations applied. Basically I want a way to apply the scale transform absolutely without affecting any other transform. Is there a way to do this? I don't think using 1.0/0.95 for the scale up factor, because it is possible the view could receive two touches before one is cancelled or ended.
I think I am asking the same thing as this question: Applying just the scale component of a CGAffineTransform to a UIView but I don't think the answers here will work for me.
I am targeting iOS 7 and above.
I am not sure if this is exactly what you are looking for but for me I need the scale to be absolutely consistent all the time so I modify the matrix directly.
CATransform3D transform = layer.transform;
if (makeSmaller)
{
// Scale to 0.9
transform.m11 = 0.9f;
transform.m22 = 0.9f;
}
// Cell needs to grow to normal size
else if (restoreToOriginal)
{
// Scale to 1.0 again
transform.m11 = 1.0f;
transform.m22 = 1.0f;
}
// Set the desired Y translation
transform.m42 = desiredffset;
layer.transform = transform;

How to rotate a CAShapeLayer at its center point

I have made a CAShapeLayer with few points by setting its stroke color to red . Then i have filled the color with a pattern of an UIImage. I want to rotate that CAShapeLayer along with its filled pattern using UIRotationGestureRecognizer.
I have used CATransform3DRotate but it is not working properly.
CATransform3D transform = CATransform3DIdentity;
transform = CATransform3DRotate(transform, recognizer.rotation, 0.0, 0.0, 1.0);
shapeLayer.transform = transform;
Thanks in advance
You'll want to call:
shapeLayer.anchorPoint = (CGPoint){0.5, 0.5};
You're also starting with the identity transform, which throws away any transformations you've done before, like positioning the layer. What you want to do is:
shapeLayer.transform = CATransform3DRotate(shapeLayer.transform, recognizer.rotation, 0.0, 0.0, 1.0);

Understanding CATransform3D

I'm playing with CATransform3DMakeRotation in a UIView, and I'm trying to do a 45ยบ, transform like it's laying backwards:
This is the "code" I have, but clearly doesn't do it.
CATransform3D _tr = CATransform3DMakeRotation(3.14/4, 1, 0, 0);
view.layer.transform = _tr;
please help me understand the params.
Thanks.
Basically, your code is correct, but to get the perspective effect, you need to set the sublayerTransform of the superview's layer to something like this:
CATransform3D perspectiveTransform = CATransform3DIdentity;
perspectiveTransform.m34 = 1.0 / -850;
myView.layer.sublayerTransform = perspectiveTransform;
You can experiment with different values for different amounts of distortion.

Resources