How to remove gesture after implementing UIGestureRecognizer - iphone

I am using PinchGestureRecognizer and RotationGestureRecognizer both working fine. The code is as follows:
- (IBAction)pinchDetected:(UIPinchGestureRecognizer *)recognizer {
recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale);
recognizer.scale = 1;
}
-(IBAction)rotationDetected:(UIRotationGestureRecognizer *)recognizer
{
recognizer.view.transform = CGAffineTransformRotate(recognizer.view.transform, recognizer.rotation);
recognizer.rotation = 0;
}
with this code I am able to pinch as well as rotate my view. but on "RESET" button click I want to set my view's frame as it was before pinching or rotating.
for that I am using
[viewTwo setFrame:CGRectMake(80.0f, 65.0f, 160.0f, 101.0f)];
but my frame does not set.
so How can I set my view's frame again as it was before pinching and zooming?

You are not changing the frame with your gesture recognisers.
You need to assign the transform back to the identity.
recognizer.view.transform = CGAffineTransformIdentity;

Frame and transform are applied to a view in two completely separate ways (where frame is the smallest rectangle that fits a view, and transform is a representation of the underlying 2-D matrix of the view). If you wish to return to the size the view was previously, assign recognizer.view.transform to CGAffineTransformIdentity.

Related

Get UIPinchGestureRecognizer finger positions

Im using the UIGestureRecognizer to transform a view and its workin perfectly, but now I want to use it to transform my view width and height independently. The only way that comes to my mind to solve this is getting the two finger positions and make an if clause to recognize if the user is trying to increase width or height, but for this I need to get each finger position involved in the Pinch Gesture. But I cant find any method to do this I was wondering if this is posible or if there is another alternative for achieving this.
- (IBAction)handlePinch:(UIPinchGestureRecognizer *)recognizer {
recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, 1);//To transform height insted of width just swap positions of the second and third parameter.
NSLog(#"%f",recognizer.scale);
recognizer.scale = 1;
}
Got the answer if somebody needs to do this, there is a method called location of touch. With this method you can get each touch x and y position. But call it when the Gesture recognizer state began because it crashes if you do it in the state changed. Save this values in some variables and you are good to go. Hope it helps someone who is interested.
- (IBAction)handlePinch:(UIPinchGestureRecognizer *)recognizer {
if(recognizer.state == UIGestureRecognizerStateBegan){
NSLog(#"pos : 0%f, %f",[recognizer locationOfTouch:0 inView:self.view].x,[recognizer locationOfTouch:0 inView:self.view].y);
NSLog(#"pos 1: %f, %f",[recognizer locationOfTouch:1 inView:self.view].x,[recognizer locationOfTouch:1 inView:self.view].y);
}
if(recognizer.state == UIGestureRecognizerStateChanged){
recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, 1);
//NSLog(#"%f",recognizer.scale);
recognizer.scale = 1;
}
if(recognizer.state == UIGestureRecognizerStateEnded){
}

Preventing a rotated CGAffineTransform from being wrecked by view autorotation

I have a subclass of a UIImageView containing some gesture recognisers that I'm using to apply transforms to itself. I'm having no issues with panning or scaling, but the rotated transform is causing problems when the device itself is rotated. Basically each time the device is rotated it will have the effect of scaling the image...
I guess it makes sense that the rotation of everything might cause problems with a rotated transform but does anyone know any ways around this kind of behaviour? Preferably something that can be implemented within the UIImageView subclass? I need other sibling views to autoresize so I can't disable "autoresize subviews" in the parent view.
Here's the code responsible for creating the rotated transform if it helps:
- (void)setUpRotation
{
UIRotationGestureRecognizer *newRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(handleRotationGesture)];
newRecognizer.delegate = self;
self.rotationRecognizer = newRecognizer;
[self addGestureRecognizer:self.rotationRecognizer];
[newRecognizer release];
self.userInteractionEnabled = YES;
}
- (void)handleRotationGesture
{
// Initial state
if(self.rotationRecognizer.state == UIGestureRecognizerStateEnded)
{
lastRotation = 0.0;
return;
}
CGFloat rotation = 0.0 - (lastRotation - self.rotationRecognizer.rotation);
CGAffineTransform currentTransform = self.transform;
self.transform = CGAffineTransformRotate(currentTransform,rotation);
lastRotation = self.rotationRecognizer.rotation;
}
This is on iOS 5.0 btw.

Using 2 UIPinchGestureRecognizers on the same UIImageView

I have an image view that I want to pinch to rescale without keeping the aspect ratio. In order to do this, I thought it might be feasible to either:
Use two pinch gesture recognisers, one that stretches horizontally, one that does so vertically.
Use one pinch recogniser but apply the two transforms one after the other.
Here's my pinch handling function:
- (void) pinch:(UIPinchGestureRecognizer *)recognizer {
static CGRect initialBounds;
if (recognizer.state == UIGestureRecognizerStateBegan)
{
initialBounds = imageView.bounds;
}
CGFloat factor = [(UIPinchGestureRecognizer *)recognizer scale];
//scale horizontally
CGAffineTransform zt = CGAffineTransformScale(CGAffineTransformIdentity,
factor-(1.0-factor), 1.0);
imageView.bounds = CGRectApplyAffineTransform(initialBounds, zt);
//now scale vertically
zt = CGAffineTransformScale(CGAffineTransformIdentity, 1.0, factor);
imageView.bounds = CGRectApplyAffineTransform(initialBounds, zt);
return;
}
For some reason, the transform is only being done vertically (last one). I tried changing the first parameter of the second CGRectApplyAffineTransform to imageView.bounds, but it still didn't work.
Can anyone please tell me where I am going wrong?
Also, when using two pinch gesture recognisers, the same thing happens - only one of them actually gets recognised.
Thanks!
Your second one is starting with a CGAffineTransformIdentity. Instead, pass in the zt.

Scaling up a UIImageView with a pinch gesture

I'm using a pinch gesture to let users increase/decrease the size of an image. I temporarily manipulate that CGAffineTransform to let the user play with the scale, then just undo it and set the frame size so that image scales with quality (CGAffineTransformScale does nothing for image quality and will only stretch out the image).
-(void)handlePinch:(UIPinchGestureRecognizer *)recognizer{
if(recognizer.state == UIGestureRecognizerStateBegan){
self.alpha = 0.7;
startingTransform = self.transform;
}
recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale);
recognizer.scale = 1;
if (recognizer.state == UIGestureRecognizerStateEnded){
self.alpha = 1.0;
CGRect endFrame = self.frame;
self.transform = startingTransform;
self.frame = endFrame;
//self.transform = CGAffineTransformRotate(self.transform, acos(startingTransform.c)); //reapply rotation?
}
}
The issue: The problem with my code is that it does not account for rotation. Some of my images start out rotated (with CGAffineTransformRotate being previously applied to them) and what happens when the pinch gesture finishes is that the imageview warps out into really thin rectangles, devoid of any rotation or scale they were before.
I thought I could carry over the original rotation and apply it after the frame was set, but I don't think that works. Any help is appreciated. Thanks
Note that the UIView documentation says that as soon as a UIViews transform is not its identity transform, the frame property becomes undefined and should not be used, so do not rely on CGRect endFrame = ... to work.
Otherwise, if you want the quality to change, just set the transform to identity, scale the frame and then reapply the transform to keep the rotation. That should work fine.
add imageview as subview of scrollview, and then specify the delegate of scrolview which asks for viewtobezoomed as the imageview. it will easi.y solve it.
http://developer.apple.com/library/ios/documentation/uikit/reference/uiscrollviewdelegate_protocol/Reference/UIScrollViewDelegate.html#//apple_ref/occ/intfm/UIScrollViewDelegate/viewForZoomingInScrollView:

iPhone4 iOS5 UIRotationGestureRecognizer, how to remember rotation offset for subsequent rotations?

I'm trying to create a knob-like behavior in one of my views with a UIRotationGestureRecognizer. This works, and positions the view as expected. However, every single time a gesture is performed, the rotation of the recognizer resets, so the knob starts at 0 every time.
How can I remember the last rotation of the UIRotationGestureRecognizer to let the user adjust the knob UIView without resetting it every single time?
I'm trying to make the recognizer start calculating rotation changes from the view's last known rotation:
knob starts at 0, recognizer is at 0
recognizer is rotated to 45 degrees
recognizer stops rotating
the knob is left at 45 degrees //this is already happening with the provided code snippet
next touch:
//this is what's is happening
recognizer starts at 0, rotates the knob back to 0
//I want it to be:
recognizer starts at 45, rotates the knob as in the example above.
- (IBAction)rotateView:(id)sender {
if([sender isKindOfClass:[UIRotationGestureRecognizer class]])
{
UIRotationGestureRecognizer* recognizer = sender;
CGAffineTransform transform = CGAffineTransformMakeRotation([recognizer rotation]);
rotatingView.transform = transform;
}
}
You should be able to get the current rotation of the rotatingView from it's transform property. Store this value into a savedRotation variable when the gesture begins. Make sure to assign a delegate to handle the gestureRecognizerShouldBegin callback.
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)recognizer
{
savedRotation = atan2(rotatingView.transform.b, rotatingView.transform.a);
return YES;
}
- (void)rotateView:(UIRotationGestureRecognizer*)recognizer
{
rotatingView.transform = CGAffineTransformMakeRotation(recognizer.rotation+savedRotation);
}
Transform the transform:
rotatingView.transform = CGAffineTransformRotate(rotatingView.transform, [recognizer rotation]);
You have to make sure that you reset the rotation after the transform. Otherwise they will stack on top of each other and you get the "interesting" behavior.
rotatingView.transform = CGAffineTransformScale(rotatingView.transform, recognizer.scale, recognizer.scale);
[recognizer setRotation:0]; // this line
You should also do this for any translation or scaling transformations that you may do when handling gestures. The methods there are:
[recognizer setScale:1];
[recognizer setTranslation:CGPointZero inView:recognizer.view.superview];