scaling & Rotation of shape (rectangle) - iphone

Please i want scaling & Rotation of shape (rectangle) from one point.
Take as an example of MS Paint.
What will be the approach for that ?
Will it be possible ?
Thanks in Advance.

Use CGAffineTransform for that.
Rotation:
myView.layer.transform = CGAffineTransformRotate(theView.transform, degreesToRadians(45));
Scaling:
myView.layer.transform = CGAffineTransformScale(theView.transform, 2.0, 2.0);
By default it scale/rotate from center.
For any point you need to set the anchor point. See example:-
myView.layer.anchorPoint = CGPointMake(0, 0);

Related

apply 3d animation to view

I'm struggling with animations and can't find anything like i want. I would like to apply a 3d rotation to a view. Like a cube rotation, the view should have two images, and rotate from one to other like iphone notification animation. Animation i want is like this one here: http://www.youtube.com/watch?v=pBgVbzBJqDc
I don't think even one way of how to do this, so any help would be very appreciated!
Thanks in advance!
You can apply a 3D animation to a view by setting a CATransform3D with the transform on the views layer. The rotation will look very flat without any perspective so you should set an appropriate value for the third row and forth column of the transform matrix.
ObjC:
CATransform3D rotation = CATransform3DIdentity;
rotation.m34 = -1.0/500.0;
rotation = CATransform3DRotate(rotation, M_PI, 1.0, 0.0, 0.0);
myView.layer.transform = rotation;
Swift:
var rotation = CATransform3DMakeRotation(CGFloat(M_PI), 1.0, 0.0, 0.0);
rotation.m34 = CGFloat(-1.0/500.0)
firstView.layer.transform = rotation;
You would give the two views suitable values for the angle and position them where they should be on screen.
To make it look like a cube rotation you could also translate the layers half the width of the cubes side (so that it doesn't rotate around the center) before rotating the transform matrix.
rotation = CATransform3DTranslate(rotation, 0.0, 0.0, sideOfCube/2.0);

Passing only one argument with CGAffineTransformMakeTranslation (x,y)

I have multiple animations on a button, and I'm using CGAffineTransformMakeTranslation to do this.
Is it possible to use only one argument with it, only "x" or only "y"?
I've tried everything but couldn't make it work:
button.transform = CGAffineTransformMakeTranslation(nil, 10);
button.transform = CGAffineTransformMakeTranslation(NULL, 10);
etc, etc...
Or make it the "x" the current location. If I use 0 it will bring the button to the original location.
Is it possible to do this?
Thanks!!
Pass 0. A translation of 0 along an axis produces no change, because 0 is the identity of addition (which is what translation is).
button.transform = CGAffineTransformMakeTranslation(0, someYValue);
Translation in x direction only:
CGAffineTransformMakeTranslation(x, 0.0);
Translation in y direction only:
CGAffineTransformMakeTranslation(0.0, y);
CGAffineTransformTranslate retains the previous transform.
You can therefore call CGAffineTransformTranslate(myview.transform,0,y) or whatever suits you.
CGAffineTransform CGAffineTransformTranslate (
CGAffineTransform t,
CGFloat tx,
CGFloat ty
);

Rotate 3D got issue in X axis

I have rotate3d one image.. Here is my code..
CALayer *layer = backImageView.layer;
CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
rotationAndPerspectiveTransform.m34 = 1.0 / -300;
rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, 15.0f * M_PI / 180.0f, 1.0f, 0.0f, 0.0f);
layer.transform = rotationAndPerspectiveTransform;
As before putting background image looks like
After
But when i put one more image as a background it looks like this..
X(-ve) - axis should not be displayed..
Is there any thing wrong in code or need to add extra logic or code ?
Thanks..
I had the same problem. Its happens becouse before rotation both images lay in the same plane, but after rotation part of the image appears behind the plane and covered by another. My solution was to drag one of the images on another plane, so they do not overlap.
grayImage.layer.transform=CATransform3DMakeTranslation(0, 0, -100);
Where grayImage your second image.

Question about rotating a slider

I am working on an application which needs to rotate the slider at one end. However, by using CGAffineTransformMakeRotation(), I can only rotate the slider at the centre.
What should I do in order to rotate the slider at the end point? If possible, please give a short paragraph of sample code. Thanks a lot.
I rotate a UIImageView by setting the anchorPoint property for the view's layer. e.g.
myView.layer.anchorPoint = CGPointMake(0.5, 1.0);
and then applying a CATransform3DRotate as the layer's transform property
CATransform3D rotationTransform = CATransform3DIdentity;
rotationTransform = CATransform3DRotate(rotationTransform, positionInRadians, 0.0, 0.0, 1.0);
myView.layer.transform = rotationTransform;
I found this from Apple's metronome example, so it's worth checking that out. Hope that helps
I second cidered's answer. To do what you want using CGAffineTransforms, you have to compose transformations until you get the effect you're looking for:
CGAffineTransform transform = CGAffineTransformMakeRotation(1.0);
transform = CGAffineTransformTranslate(transform, slider.frame.size.width / 2, 0.0);
slider.transform = transform;

Can i move the origin when doing a rotation transform in Quartz 2D for the iPhone?

Sorry if this is obvious or covered elsewhere, but i've been googling all day and haven't found a solution that actually worked.
My problem is as follows: I am currently drawing an image in a full screen UIView, for examples sake we'll say the image is in the bottom right corner of the UIView. I'd like to do a rotation transform(CGAffineTransformMakeRotation) at the center of that image, however, by default the rotation command rotates around the center of the UIView it self. As a result, my image moves around the screen when i rotate instead of it staying in place and rotating around its own center.
From what i've gathered, i need to translate my context so that the origin(center of the UIView) is at the center of my image, Rotate, and then restore the context by translating back to the original spot.
The following is the closest thing i've gotten to work, but the problem is that while the image is rotating, it moves downward while it's rotating. I think this is caused by animation tweening the 1st step translate and 3rd step translate instead of just realizing that the beginning and end point on the translates would be the same...
// Before this i'd make a call to a function that draws a path to a passed in context
CGAffineTransform inverseTranslation = CGAffineTransformMakeTranslation( transX, transY );
CGAffineTransform translation = CGAffineTransformMakeTranslation( -transX, -transY );
CGAffineTransform rot = CGAffineTransformMakeRotation( 3.14 );
CGAffineTransform final = CGAffineTransformConcat( CGAffineTransformConcat( inverseTranslation, rot ), translation );
// Then i apply the transformation animation like normal using self.transform = final etc etc
I've also tried stuff like CGContextTranslateCTM and CGContextSaveGState/UIGraphicsPushContext, but these seem to have little effect.
I've been fighting with this for days and my current solution seems close, but i have no clue how to get rid of that translating tweening. Does anyone have a solution for this or a better way to go about this?
[update]
For the time being i'm drawing my image centered at the UIview's center and then setting the UIView.center property to the origin i'd like to rotate and then doing the rotate command. Seems like a bit of a hack, but until i can get the real translates working it's my only choice.
Thanks!
duncanwilcox' answer is the right one, but he left out the part where you change the anchor of the view's layer to the point you want to rotate around.
CGSize sz = theview.bounds.size;
// Anchorpoint coords are between 0.0 and 1.0
theview.layer.anchorPoint = CGPointMake(rotPoint.x/sz.width, rotPoint.y/sz.height);
[UIView beginAnimations:#"rotate" context:nil];
theview.transform = CGAffineTransformMakeRotation( 45. / 180. * M_PI );
[UIView commitAnimations];
This is documented here: http://developer.apple.com/documentation/Cocoa/Conceptual/CoreAnimation_guide/Articles/Layers.html
This is also an option: a simple change of basis ;-)
CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y);
transform = CGAffineTransformRotate(transform, angle);
transform = CGAffineTransformTranslate(transform,-x,-y);
where (x,y) is the rotation center you like
Rotation happens around the anchorPoint of the view's layer. The default for the anchorPoint is the center (0.5, 0.5), so the rotation alone without the translations should suffice.
Did a quick test and this works for me:
[UIView beginAnimations:#"rotate" context:nil];
self.transform = CGAffineTransformMakeRotation( 45. / 180. * 3.14 );
[UIView commitAnimations];
If you don't want an animation to occur, but just set the new rotation, you can use this:
CGFloat newRotation = 3.14f
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.0]; // no tweening
CGAffineTransform transform = CGAffineTransformMakeRotation(newRotation);
self.transform = transform;
[UIView commitAnimations];
The rotation should indeed take place around the center of the UIView. Setting the animationDuration to zero garantees no tweening should happen.
Be sure though you don't do this 60 times a second. It's very tempting to create game like animations with these tools. These kind of animations aren't exactly meant for a frame to frame based, "lots of sprites flying everywhere" game.
For that - and I've been down that road - the only way to go, is OpenGL.