Image Resize when rotate using UIRotationGestureRecognizer in iphone application - iphone

I add One ScrollView in that i put image when i resize image using viewForZoomingInScrollView
after that i Rotate image using UIRotationGestureRecognizer at that time image getting resize automatically so any solution for this problem.
here i put code for zoom and rotate:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return Photo;
}
/*In response to a rotation gesture, show the image view at the rotation given by the recognizer, then make it fade out in place while rotating back to horizontal.
*/
- (void)handleRotationFrom:(UIRotationGestureRecognizer *)recognizer {
CGAffineTransform transform = CGAffineTransformMakeRotation([recognizer rotation]);
Photo.transform = transform;
}

Implement class EditImageView
handle touch over there for tracking touch.

Related

Pinchgesture not working for small images

Im using GestureRecognizer delegate for pinch,pan,rotate,longpress for images. I used UIPinchGestureRecognizer delegate for pinching.
But, when i pinch zoomIn it doesn't have any problem. When i zoomOut certain level the images are small, and i can't ZoomIn pinching the images. After that, when i apply pan, the pan is applying whole view and only the image while i release my finger. After release my finger,the pan is apply only image. After touch the image pan apply on whole view
code:
UIPinchGestureRecognizer *pinchGesture1 = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(ahandlePinch1:)];
[myImageView addGestureRecognizer:pinchGesture1];
-(void)ahandlePinch1:(UIPinchGestureRecognizer*)sender {
mCurrentScale += [sender scale] - mLastScale;
mLastScale = [sender scale];
if (sender.state == UIGestureRecognizerStateEnded)
{
mLastScale = 1.0;
}
CGAffineTransform currentTransform = CGAffineTransformIdentity;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, mCurrentScale, mCurrentScale);
myImageView.transform = newTransform;
}
You should modify your ahandlePinch1 method so that you don't reduce the size of the image below a certain amount. It is almost certainly getting so small that it can no longer detect two distinct touches (which are required for the pinch gesture).
Apple generally recommend allowing a minimum of 44x44 pts as a touchable area, so I would suggest you stop your image from resizing below 88x88.
Alternatively, if you actually need your image to be less than that then you should add the gesture recognizer to a different view (perhaps the superview), rather than the image itself.

iPhone iOS how to make UIRotationGestureRecognizer and UIPinchGestureRecognizer to work together to scale and rotate a UIView with subviews?

I'm implementing a drag/drop/resize/rotate labels within my app. So far everything is working except for the UIRotationGestureRecognizer gesture. More specifically, it does not work with the UIPinchGestureRecognizer gesture.
Normally the two gestures compete for two finger touches, so I'm running them in parallel. Below are my 2 methods that the gesture recognizers invoke.
When doing the rotation gesture, the view spins wildly around it's center, with it's height and width changing as follows: height becomes width, width slowly turns into height. Eventually, the view disappears.
Within the view, I have another auto-resizing view. Normally, the pinch gesture automatically resizes the subviews as well, but in this case the subviews with autoresizing masks disappear. The subviews have height and width springs and left/top strut.
What am I doing wrong? How can I both resize and scale a UIView with gestures?
All the delegate methods and connections are setup properly. I need to understand how to handle the order in which the recognizers would be applying the scaling and rotation.
//makes 2 gesture recognizers behave together
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
- (IBAction)handleRotationFrom:(id)sender {
NSLog(#"Gesture rotation %.1f", rotationGestureRecognizer.rotation);
//attempt to continuously rotate the label, starting with a remembered rotation
float rotation = atan2(activeCompanionLabelView.transform.b, activeCompanionLabelView.transform.a);
NSLog(#"existing rotation %.1f", rotation);
// rotation = rotation<0?(2*M_PI)-fabs(rotation):rotation;
rotation +=rotationGestureRecognizer.rotation;
NSLog(#"*** gesture rotation %.1f sum: %.1f, saved: %.1f",rotationGestureRecognizer.rotation, rotation, activeCompanionLabelView.savedRotation);
activeCompanionLabelView.transform = CGAffineTransformMakeRotation((rotation));
activeCompanionLabelView.savedRotation = rotation;
}
- (IBAction)handlePinch:(id)sender {
NSLog(#"pinch %.2f", pinchGestureRecognizer.scale);
//resize, keeping the origin where it was before
activeCompanionLabelView.frame = CGRectMake(activeLabelContainerFrame.origin.x, activeLabelContainerFrame.origin.y, activeLabelContainerFrame.size.width*pinchGestureRecognizer.scale, activeLabelContainerFrame.size.height*pinchGestureRecognizer.scale);
}
If you want two gestureRecognisers to run in parallel (simultaneously) your
view should implement <UIGestureRecognizerDelegate>.
Also, you should make it a delegate of both gestureRecognizers.
rotationGestureRecognizer.delegate=self;
pinchGestureRecognizer.delegate=self;
And you also should implement shouldRecognizeSimultaneouslyWithGestureRecognizer: method:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
NOTE: if you have more then this two gestureRecognisers in your view you're gonna have to add some identity checking in this method.
EDIT:
Just found Ole Begemann's article on this topic: Gesture Recognition on iOS with Attention to Detail

How to rotate a CGRect or CGImageCreateWithImageInRect?

To describe my project:
I have a rectangle UIImageView frame floating over a white layer. Inside the UIImageView, I'm successfully creating the illusion that it is showing a portion of a background image behind the white layer. You can drag the rectangle around, and it will "redraw" the image so that you can peer into what is behind the white. Its basically this code:
//whenever the frame is moved, updated the CGRect frameRect and run this:
self.newCroppedImage = CGImageCreateWithImageInRect([bgImage.image CGImage], frameRect);
frame.image = [UIImage imageWithCGImage:self.newCroppedImage];
Anyhow, I also have a rotation gesture recognizer that allows the user to rotate the frame (and consequentially rotates the image). This is because the CGRect sent to the CGImageCreateWithImageInRect is still oriented at its original rotation. This breaks the illusion that you're looking through a window because the image you see is rotated when only the frame should appear that way.
So ideally, I need to take the rotation of my frame and apply it to the image created from my bgImage. Does anyone have any clues or ideas on how I could apply this?
I suggest you take a different approach. Don't constantly create new images to put in your UIImageView. Instead, set up your view hierarchy like this:
White view
"Hole" view (just a regular UIView)
Image view
That is, the white view has the hole view as a subview. The hole view has the UIImageView as its subview.
The hole view must have its clipsToBounds property set to YES (you can set it with code or in your nib).
The image view should have its size set to the size of its image. This will of course be larger than the size of the hole view.
And this is very very important: the image view's center must be set to the hole view's center.
Here's the code I used in my test project to set things up. The white view is self.view. I start with the hole centered in the white view, and I set the image view's center to the hole view's center.
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
CGRect bounds = self.view.bounds;
self.holeView.center = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
self.holeView.clipsToBounds = YES;
bounds = self.holeView.bounds;
self.imageView.center = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
self.imageView.bounds = (CGRect){ CGPointZero, self.imageView.image.size };
}
I also set the image view's size to the size of its image. You might want to set it to the size of the white view.
To pan and rotate the hole, I'm going to set holeView.transform. I'm not going to change holeView.frame or holeView.center. I have two instance variables, _holeOffset and _holeRotation, that I use to compute the transform. The trick to making it seem like a hole through the white view, revealing the image view, is to apply the inverse transform to the image view, undoing the effects of the hole view's transform:
- (void)updateTransforms {
CGAffineTransform holeTransform = CGAffineTransformIdentity;
holeTransform = CGAffineTransformTranslate(holeTransform, _holeOffset.x, _holeOffset.y);
holeTransform = CGAffineTransformRotate(holeTransform, _holeRotation);
self.holeView.transform = holeTransform;
self.imageView.transform = CGAffineTransformInvert(holeTransform);
}
This trick of using the inverse transform on the subview only works if the center of the subview is at the center of its superview. (Technically the anchor points have to line up, but by default the anchor point of a view is its center.)
I put a UIPanGestureRecognizer on holeView. I configured it to send panGesture: to my view controller:
- (IBAction)panGesture:(UIPanGestureRecognizer *)sender {
CGPoint offset = [sender translationInView:self.view];
[sender setTranslation:CGPointZero inView:self.view];
_holeOffset.x += offset.x;
_holeOffset.y += offset.y;
[self updateTransforms];
}
I also put a UIRotationGestureRecognizer on holeView. I configured it to send rotationGesture: to my view controller:
- (IBAction)rotationGesture:(UIRotationGestureRecognizer *)sender {
_holeRotation += sender.rotation;
sender.rotation = 0;
[self updateTransforms];
}

UIScrollView zoom issue with UIRotationGestureRecognizer

I have a scroll view which shows a image view. I am trying to handle UIRotationGestureRecognizer on the image view. I get the event for rotation and apply the required transform on the same. The image gets properly rotated in the scroll view. Then when I do any operations in the scroll view like zoom or pan the image rotation and position goes for a toss
_mainView is the subView of UIScrollView which is also used for zooming
UIRotationGestureRecognizer *rotationGesture=[[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotationGesture:)];
[_mainView addGestureRecognizer:rotationGesture];
[rotationGesture release];
-(void) rotationGesture:(UIRotationGestureRecognizer *) sender {
if(sender.state == UIGestureRecognizerStateBegan ||
sender.state == UIGestureRecognizerStateChanged)
{
sender.view.transform = CGAffineTransformRotate(sender.view.transform,
sender.rotation);
_currRotation = _currRotation + sender.rotation;
[sender setRotation:0];
}
}
I will like to understand what would be the right way to handling rotation with-in the scroll view and it maintains that rotation even after zoom events in Scroll View.
Implement the gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: method in your UIGestureRecognizerDelegate, and return all gestures you want to recognize simultaneously. If you still have trouble with it, check out the answers to UIImageView Gestures (Zoom, Rotate) Question.
Good luck!
EDIT: Your comment has me guessing that the issue is that you can only have one transform on at a time, and the scroll view applies a scale transform, replacing the rotation one. You could remove the native zoom recognizer (see this question), or nest another UIView in the scroll view, and apply the rotation transform to that. I like option two, it seems easier. If you go with option one, use CGAffineTransformConcat to apply both the zoom and rotate transformations independently.

How to have images that do not resize when zooming in a UIScrollView?

I want to have images inside of a UIScrollView (or at least appear to be inside a UIScrollView) that don't change their size when zooming in and out. I do want the images to maintain their positions when zooming or scrolling.
The use case is that I have a customized map view with pushpins. I want the pushpins to stay in place when zooming and scrolling the map, but I don't want them to be "zoomed in" with the content.
What is the best way to do this?
You can have your pushpin image(s) as a subview of your UIScrollView but not a subview of the view returned by
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
Then, in scrollViewDidZoom adjust the pushpin x and y by the zoomScale to keep the pins correctly positioned:
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
imageView.frame = CGRectMake(pushPinX * scrollView.zoomScale, pushPinY * scrollView.zoomScale, imageView.frame.size.width, imageView.frame.size.height);
}