CGAffineTransformMakeTranslation Movement - iphone

I am using CGAffineTransformMakeTranslation with UIPanGestureRecognizer to pan a UIView.
Does CGAffineTransformMakeTranslation take delta x and delta y or the absolute value of the new position? Here's what I have:
- (void)swipeDetected:(UIPanGestureRecognizer *)recognizer
{
CGPoint newTranslation = [recognizer translationInView:self.view];
self.navController.view.transform = CGAffineTransformMakeTranslation(newTranslation.x, 0);
.....
}
This works from left to right but not from right to left. I'm pretty sure "translation" means delta x and delta y and not absolute value.
Any suggestions?
Thanks

Setting the transform is an immediate operation as it is just matrix multiplication of the view's location.
If you need to revert back from your current position, you can save the transform to an ivar, and use an inverse transform, ie:
_currentTransform = CGAffineTransformMakeTranslation(newTranslation.x, 0);
and later:
CGAffineTransform inverse = CGAffineTransformInvert(_currentTransform);
If you want to remove all transforms you can do self.transform = CGAffineTransformIdentity
Hope this helps!

Related

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

CGPoint rotation changes distance from origin

I want to rotate a CGPoint(red rect) around another CGPoint(blue rect) but it changes distance from the origin(blue rect)...when i give 270 in angle it creates the point right above the origin but when i give 90 as angle value it comes down the origin BUT CHANGES THE DISTANCE ALSO almost three times more....I want to keep the distance same and want to rotate CGPoint around another. Please guide any approach for rotation of cgpoints...
distance = 100;
angle = 270*M_PI/180;
rotatedPoint.x = initialPoint.x+distance*cos(angle);
rotatedPoint.y = initialPoint.y+distance*sin(angle);
//rotatedPoint.x = initialPoint.x+tan(angle);
[test setCenter:rotatedPoint];
[test setBackgroundColor:[UIColor redColor]];
Thanks
CGAffineTransform is a handy tool when it comes to rotation, translation, and scaling. To make sure a point is rotated properly, you must translate it to the origin, rotate it, and then translate it back.
To complete your transformation, something like the following should do the trick:
CGPoint pointToRotate = CGPointMake(30, 30);
float angleInRadians = DEGREES_TO_RADIANS(90);
CGPoint distanceFromOrigin = CGPointMake(0 - pointToRotate.x, 0 - pointToRotate.y);
CGAffineTransform translateToOrigin = CGAffineTransformMakeTranslation(distanceFromOrigin.x, distanceFromOrigin.y);
CGAffineTransform rotationTransform = CGAffineTransformMakeRotation(angleInRadians);
CGAffineTransform translateBackFromOrigin = CGAffineTransformInvert(translateToOrigin);
CGAffineTransform totalTransform = CGAffineTransformConcat(translateToOrigin, rotationTransform);
totalTransform = CGAffineTransformConcat(totalTransform, translateBackFromOrigin);
pointToRotate = CGPointApplyAffineTransform(pointToRotate, totalTransform);
And here is the documentation on CGAffineTransform, if you'd like to review it further: http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Reference/CGAffineTransform/Reference/reference.html
Please let me know if you need anything else if this doesn't solve your problem!

Co-ordinates of the four points of a uiview which has been rotated

Is it possible to get this? If so, can anyone please tell me how?
Get the four points of the frame of your view (view.frame)
Retrieve the CGAffineTransform applied to your view (view.transform)
Then apply this same affine transform to the four points using CGPointApplyAffineTransform (and sibling methods of the CGAffineTransform Reference)
CGPoint topLeft = view.bounds.origin;
topLeft = [[view superview] convertPoint:topLeft fromView:view];
CGPoint topRight = CGPointMake(view.bounds.origin.x + view.bounds.width, view.bounds.origin.y);
topRight = [[view superview] convertPoint:topRight fromView:view];
// ... likewise for the other points
The first point is in the view's coordinate space, which is always "upright". Then the next statement finds the point that point corresponds to in the parent view's coordinate space. Note for an un-transformed view, that would be equal to view.frame.origin. The above calculations give the equivalent of the corners of view.frame for a transformed view.

Set center point of UIView after CGAffineTransformMakeRotation

I have a UIView that I want the user to be able to drag around the screen.
-(void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
CGPoint pt = [[touches anyObject] locationInView:self];
CGPoint center = self.center;
CGFloat adjustmentX = pt.x - startLocation.x;
CGFloat adjustmentY = pt.y - startLocation.y;
center.x += adjustmentX;
center.y += adjustmentY;
[self setCenter:center];
}
works perfectly until I apply a transform to the view as follows:
self.transform = CGAffineTransformMakeRotation(....);
However, once the transform has been applied, dragging the UIView results in the view being moved in a exponential spiral effect.
I'm assuming I have to make an correction for the rotation in the touchesMoved method, but so far all attempts have eluded me.
You need to translate your transform to your new coordinates because a transform other than the identity is assigned to your view and moving its center alters the transform's results.
Try this instead of altering your view's center
self.transform = CGAffineTransformTranslate(self.transform, adjustmentX, adjustmentY);

Check UIButton position after rotating UIView

I have a buttonsthat I add on a UIImageView. With a method when the user touch the screen
the UIImageView will rotate, I want to know if there is a way to get the new position of the button after the rotation is done.
Right now I'm getting all the time the original position with this method :
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"Xposition : %f", myButton.frame.origin.x);
NSLog(#"Yposition : %f", myButton.frame.origin.y);
}
Thanks,
This is a tricky question. Referring to the UIView documentation on the frame property it states:
Warning: If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored.
So the trick is finding a workaround, and it depends on what exactly you need. If you just need an approximation, or if your rotation is always a multiple of 90 degrees, the CGRectApplyAffineTransform() function might work well enough. Pass it the (untransformed) frame of the UIButton of interest, along with the button's current transform and it will give you a transformed rect. Note that since a rect is defined as an origin, width and height, it can't define a rectangle with sides not parallel to the screen edges. In the case that it isn't parallel, it will return the smallest possible bounding rectangle for the rotated rect.
Now if you need to know the exact coordinates of one or all of the transformed points, I've written code to compute them before, but it's a bit more involved:
- (void)computeCornersOfTransformedView:(UIView*)transformedView relativeToView:(UIView*)parentView {
/* Computes the coordinates of each corner of transformedView in the coordinate system
* of parentView. Each is corner represented by an independent CGPoint. Doesn't do anything
* with the transformed points because this is, after all, just an example.
*/
// Cache the current transform, and restore the view to a normal position and size.
CGAffineTransform cachedTransform = transformedView.transform;
transformedView.transform = CGAffineTransformIdentity;
// Note each of the (untransformed) points of interest.
CGPoint topLeft = CGPointMake(0, 0);
CGPoint bottomLeft = CGPointMake(0, transformedView.frame.size.height);
CGPoint bottomRight = CGPointMake(transformedView.frame.size.width, transformedView.frame.size.height);
CGPoint topRight = CGPointMake(transformedView.frame.size.width, 0);
// Re-apply the transform.
transformedView.transform = cachedTransform;
// Use handy built-in UIView methods to convert the points.
topLeft = [transformedView convertPoint:topLeft toView:parentView];
bottomLeft = [transformedView convertPoint:bottomLeft toView:parentView];
bottomRight = [transformedView convertPoint:bottomRight toView:parentView];
topRight = [transformedView convertPoint:topRight toView:parentView];
// Do something with the newly acquired points.
}
Please forgive any minor errors in the code, I wrote it in the browser. Not the most helpful IDE...