I want to crop an UIImageView in rectangular size and it Should be resizable, Please anyone help me, I am struggling.
You can use below code to add pan gesture from which you can move the imageview and pinch gesture through which you can resize the image
-(void)addGesture {
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(move:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[imgView addGestureRecognizer:panRecognizer];
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(resize:)];
[imgView addGestureRecognizer:pinchRecognizer];
}
-(void)move:(id)sender {
[self.view bringSubviewToFront:[(UIPanGestureRecognizer*)sender view]];
CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender translationInView:self.view];
if ([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
firstX = [[sender view] center].x;
firstY = [[sender view] center].y;
}
translatedPoint = CGPointMake(firstX+translatedPoint.x, firstY);
[[sender view] setCenter:translatedPoint];
}
- (void)resize:(UIPinchGestureRecognizer *)recognizer
{
if([recognizer state] == UIGestureRecognizerStateBegan) {
_lastScale = 1.0;
if ([recognizer numberOfTouches] >= 2) { //should always be true when using a PinchGR
CGPoint touch1 = [recognizer locationOfTouch:0 inView:self.imageForEditing];
CGPoint touch2 = [recognizer locationOfTouch:1 inView:self.imageForEditing];
CGPoint mid;
mid.x = ((touch2.x - touch1.x) / 2) + touch1.x;
mid.y = ((touch2.y - touch1.y) / 2) + touch1.y;
CGSize imageViewSize = self.imageForEditing.frame.size;
CGPoint anchor;
anchor.x = mid.x / imageViewSize.width;
anchor.y = mid.y / imageViewSize.height;
self.imageForEditing.layer.anchorPoint = anchor;
}
}
CGFloat scale = 1.0 - (_lastScale - [recognizer scale]);
CGAffineTransform currentTransform = self.imageForEditing.transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
[self.imageForEditing setTransform:newTransform];
_lastScale = [recognizer scale];
}
Related
I was adding multiple gestures in one view, The view have a one close button at corner of the view, Everything is working fine but when I am zoom that view close button was also zoom with that view, Now I want to zoom only that view not that close button, Please suggest me How to do this ?
see below image for reference.
Code for pinch Zoom
-(void)addStickersWithView:(UIView*)view image:(UIImage*)image{
CGPoint center = self.imgPhoto.center;
UIImageView *imgView = [[UIImageView alloc] initWithImage:image];
UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotatePiece:)];
[imgView setContentMode:UIViewContentModeScaleToFill];
UIView *viewZoom = [[UIView alloc] initWithFrame:CGRectMake(center.x-45,center.y-45, 90, 90)];
// [viewZoom setBackgroundColor:[UIColor redColor]];
imgView.frame = CGRectMake(5, 5, CGRectGetWidth(viewZoom.frame)-10, CGRectGetHeight(viewZoom.frame)-10);
[viewZoom addSubview:imgView];
[viewZoom addGestureRecognizer:rotationGesture];
UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(scalePiece:)];
[pinchGesture setDelegate:self];
[viewZoom addGestureRecognizer:pinchGesture];
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(moveImage:)];
[panGesture setMinimumNumberOfTouches:1];
[panGesture setMaximumNumberOfTouches:1];
[viewZoom addGestureRecognizer:panGesture];
UIButton *btnCloseSticker = [UIButton buttonWithType:UIButtonTypeCustom];
[btnCloseSticker setBounds:CGRectMake(0, 0, 30,30)];
[btnCloseSticker setImage:[UIImage imageNamed:#"close1.png"] forState:UIControlStateNormal];
[btnCloseSticker addTarget:self action:#selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
self.stickerCount++;
btnCloseSticker.tag = self.stickerCount;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(TapToShowClose:)];
tapGesture.numberOfTapsRequired = 2;
[viewZoom addGestureRecognizer:tapGesture];
viewZoom.layer.borderColor = [UIColor whiteColor].CGColor;
viewZoom.layer.borderWidth = 3.0;
viewZoom.tag = self.stickerCount+kTagBorder;
[viewZoom addSubview:btnCloseSticker];
[view addSubview:viewZoom];
}
-(void)hideShowBorderCloseButton{
int borderCount = self.stickerCount-kTagBorder;
for(int i=1;i<=borderCount;i++){
UIView *view = [self.viewStickers viewWithTag:i+kTagBorder];
UIView *view1 = [self.viewStickers viewWithTag:i+(kTagBorder*2)];
view.hidden = YES;
view1.layer.borderWidth = 0.0;
}
}
-(void)buttonPressed:(id)sender{
UIView *view = [sender superview];
[view removeFromSuperview];
self.stickerCount--;
}
- (void)scalePiece:(UIPinchGestureRecognizer *)gestureRecognizer {
if([gestureRecognizer state] == UIGestureRecognizerStateBegan) {
// Reset the last scale, necessary if there are multiple objects with different scales
lastScale = [gestureRecognizer scale];
}
UIButton *btn = [self.viewStickers viewWithTag:gestureRecognizer.view.tag-kTagBorder];
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan ||
[gestureRecognizer state] == UIGestureRecognizerStateChanged) {
CGFloat currentScale = [[[gestureRecognizer view].layer valueForKeyPath:#"transform.scale"] floatValue];
// Constants to adjust the max/min values of zoom
const CGFloat kMaxScale = 3.0;
const CGFloat kMinScale = 1.0;
CGFloat newScale = 1 - (lastScale - [gestureRecognizer scale]);
newScale = MIN(newScale, kMaxScale / currentScale);
newScale = MAX(newScale, kMinScale / currentScale);
CGAffineTransform transform = CGAffineTransformScale([[gestureRecognizer view] transform], newScale, newScale);
[gestureRecognizer view].transform = transform;
lastScale = [gestureRecognizer scale]; // Store the previous scale factor for the next pinch gesture call
}
}
-(void)TapToShowClose:(UITapGestureRecognizer *)gestureRecognizer{
//int borderCount = self.stickerCount-kTagBorder;
UIView *view = gestureRecognizer.view; //cast pointer to the derived class if needed
view.layer.borderWidth = 2.0;
UIView *view1 = [self.viewStickers viewWithTag:view.tag-kTagBorder];
[(UIButton*)view1 setImage:[UIImage imageNamed:#"close1.png"] forState:UIControlStateNormal];
[view1 setBounds:CGRectMake(0, 0, 30,30)];
view1.hidden = NO;
}
- (void)moveImage:(UIPanGestureRecognizer *)recognizer
{
CGPoint newCenter = [recognizer translationInView:self.view];
[self hideShowBorderCloseButton];
if([recognizer state] == UIGestureRecognizerStateBegan) {
beginX = recognizer.view.center.x;
beginY = recognizer.view.center.y;
}
newCenter = CGPointMake(beginX + newCenter.x, beginY + newCenter.y);
[recognizer.view setCenter:newCenter];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
// if the gesture recognizers are on different views, don't allow simultaneous recognition
if (gestureRecognizer.view != otherGestureRecognizer.view)
return NO;
// if either of the gesture recognizers is the long press, don't allow simultaneous recognition
if ([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]] || [otherGestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]])
return NO;
return YES;
}
- (void)rotatePiece:(UIRotationGestureRecognizer *)gestureRecognizer {
[self adjustAnchorPointForGestureRecognizer:gestureRecognizer];
[self hideShowBorderCloseButton];
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) {
[gestureRecognizer view].transform = CGAffineTransformRotate([[gestureRecognizer view] transform], [gestureRecognizer rotation]);
[gestureRecognizer setRotation:0];
}
}
- (void)adjustAnchorPointForGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer {
[self hideShowBorderCloseButton];
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
UIView *piece = gestureRecognizer.view;
CGPoint locationInView = [gestureRecognizer locationInView:piece];
CGPoint locationInSuperview = [gestureRecognizer locationInView:piece.superview];
piece.layer.anchorPoint = CGPointMake(locationInView.x / piece.bounds.size.width, locationInView.y / piece.bounds.size.height);
piece.center = locationInSuperview;
}
}
In place of scaling view. it's batter to calculate the frame with your zoom level. and update the frame of the view. check out the below method.
- (IBAction)scalePiece:(UIPinchGestureRecognizer *)gestureRecognizer {
if([gestureRecognizer state] == UIGestureRecognizerStateBegan) {
// Reset the last scale, necessary if there are multiple objects with different scales
lastScale = [gestureRecognizer scale];
}
if ([gestureRecognizer state] == UIGestureRecognizerStateBegan ||
[gestureRecognizer state] == UIGestureRecognizerStateChanged) {
CGFloat newScale = 1 - (lastScale - [gestureRecognizer scale]);
[self changeScale:newScale];
lastScale = [gestureRecognizer scale]; // Store the previous scale factor for the next pinch gesture call
}
}
-(void)changeScale :(float)newScale{
CGAffineTransform transform = CGAffineTransformScale([viewForpinch transform], newScale, newScale);
viewForpinch.transform = transform;
float scale = viewForpinch.transform.a;
float buttonScale = 1 / scale;
btnl.transform= CGAffineTransformScale(CGAffineTransformIdentity, buttonScale, buttonScale);
}
The easy way to do it is to remove the close button from that view, and add it on top of the view you're zooming with a different view.
You can use. insertSubview:aboveSubview:
When I apply panDetected like this, the image is moving everywhere on the screen. I just want this feature to at the top in specific rectangle. What should I change?
-(void) panDetected: (UIPanGestureRecognizer * ) panRecognizer {
CGPoint translation = [panRecognizer translationInView: self.documentImageView];
CGPoint imageViewPosition = self.documentImageView.center;
imageViewPosition.x += translation.x;
imageViewPosition.y += translation.y;
self.documentImageView.center = imageViewPosition;
[panRecognizer setTranslation: CGPointZero inView: self.view];
}
And this one is just allowing me to zoom on the pic but only from middle point not every point on the pic.
-(void) handlePinchWithGestureRecognizer: (UIPinchGestureRecognizer * ) pinchGestureRecognizer {
CGFloat lastScale = 1.0;
if ([pinchGestureRecognizer state] == UIGestureRecognizerStateBegan) {
// Reset the last scale, necessary if there are multiple objects with different scales
lastScale = [pinchGestureRecognizer scale];
}
if ([pinchGestureRecognizer state] == UIGestureRecognizerStateBegan || [pinchGestureRecognizer state] == UIGestureRecognizerStateChanged) {
CGFloat currentScale = [
[
[pinchGestureRecognizer view].layer valueForKeyPath: #
"transform.scale"] floatValue];
// Constants to adjust the max/min values of zoom
const CGFloat kMaxScale = 1.15;
const CGFloat kMinScale = 1.0;
CGFloat newScale = 1 - (lastScale - [pinchGestureRecognizer scale]);
newScale = MIN(newScale, kMaxScale / currentScale);
newScale = MAX(newScale, kMinScale / currentScale);
self.documentImageView.transform = CGAffineTransformScale(self.documentImageView.transform, newScale, newScale);
lastScale = [pinchGestureRecognizer scale]; // Store the previous scale factor for the next pinch gesture call
}
}
-(void) setExtractedImageForTableView: (UIImage * ) extractedImage {
self.documentImageView.image = nil;
self.documentImageView = nil;
self.documentImageView = [
[UIImageView alloc] initWithImage: extractedImage];
self.documentImageView.userInteractionEnabled = YES;
UIPinchGestureRecognizer * pinchGestureRecognizer = [
[UIPinchGestureRecognizer alloc] initWithTarget: self action: #selector(handlePinchWithGestureRecognizer: )];
[self.documentImageView addGestureRecognizer: pinchGestureRecognizer];
UIPanGestureRecognizer * panRecognizer = [
[UIPanGestureRecognizer alloc] initWithTarget: self action: #selector(panDetected: )];
[self.documentImageView addGestureRecognizer: panRecognizer];
self.documentImageView.contentMode = UIViewContentModeScaleAspectFit;
if (!CGSizeEqualToSize(extractedImage.size, CGSizeZero)) {
self.documentImageView.frame = CGRectMake(CGRectGetMinX(self.view.frame), CGRectGetMinY(self.tableView.frame), CGRectGetWidth(self.view.frame), (extractedImage.size.height / extractedImage.size.width) * CGRectGetWidth(self.view.frame));
self.tableView.tableHeaderView = self.documentImageView;
[self.tableView setContentOffset: CGPointZero animated: YES];
CGRect frame = self.documentImageView.frame;
frame.size.height = self.documentImageView.frame.size.height + 100;
self.tableView.frame = CGRectMake(0, 0, 200, 200);
self.tableView.tableHeaderView.frame = frame;
}
}
You can use UIGestureRecognizerDelegate to acheve this.
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldReceiveTouch:(UITouch *)touch
The method above asks the delegate if a gesture recognizer should receive an object representing a touch. Therefore, you can check touch location and return NO when its not in the desired area.
Now i develop an app that all user drag, rotate and scale image inside uiview. but when i want to save image view data like rotate value and scale value. i found scale value from [[img.layer valueForKeyPath:#"transform.scale"] floatValue] diff with scale that i found. the scale value is like below.
-(void)scale:(id)sender {
if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
_lastScale = 1.0;
}
CGFloat scale = 1.0 - (_lastScale - [(UIPinchGestureRecognizer*)sender scale]);
//CGFloat scale = 1.0 + ([(UIPinchGestureRecognizer *)sender scale] - _lastScale);
CGAffineTransform currentTransform = self.transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
[self setTransform:newTransform];
_lastScale = [(UIPinchGestureRecognizer*)sender scale];
CGFloat size = [[self.layer valueForKeyPath:#"transform.scale"] floatValue];
self.saveScale = _lastScale;
NSLog(#"Scale %f %f",_lastScale, size);
}
so the save scale value is diff with [[img.layer valueForKeyPath:#"transform.scale"].
PLEASE HELP!!!
Declare Variable -> CGFloat currentScale;
- (void) handlePinches:(UIPinchGestureRecognizer*)paramSender{
if (paramSender.state == UIGestureRecognizerStateEnded){
currentScale = paramSender.scale;
} else if (paramSender.state == UIGestureRecognizerStateBegan &&
self.currentScale != 0.0f){
paramSender.scale = currentScale;
}
if (paramSender.scale != NAN &&
paramSender.scale != 0.0){
paramSender.view.transform =
CGAffineTransformMakeScale(paramSender.scale,
paramSender.scale);
}
}
try this
You need to add Delegate
#interface MyClass : MySuperClass <UIGestureRecognizerDelegate>
- (void)viewDidLoad
{
[super viewDidLoad];
// set up the image view
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"someImage"]];
[imageView setBounds:CGRectMake(0.0, 0.0, 120.0, 120.0)];
[imageView setCenter:self.view.center];
[imageView setUserInteractionEnabled:YES]; // <--- This is very important
// create and configure the pinch gesture
UIPinchGestureRecognizer *pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(pinchGestureDetected:)];
[pinchGestureRecognizer setDelegate:self];
[imageView addGestureRecognizer:pinchGestureRecognizer];
// create and configure the rotation gesture
UIRotationGestureRecognizer *rotationGestureRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotationGestureDetected:)];
[rotationGestureRecognizer setDelegate:self];
[imageView addGestureRecognizer:rotationGestureRecognizer];
[self.view addSubview:imageView]; // add the image view as a subview of the view controllers view
}
add this two methods
- (void)pinchGestureDetected:(UIPinchGestureRecognizer *)recognizer
{
UIGestureRecognizerState state = [recognizer state];
if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged)
{
CGFloat scale = [recognizer scale];
[recognizer.view setTransform:CGAffineTransformScale(recognizer.view.transform, scale, scale)];
[recognizer setScale:1.0];
}
}
- (void)rotationGestureDetected:(UIRotationGestureRecognizer *)recognizer
{
UIGestureRecognizerState state = [recognizer state];
if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged)
{
CGFloat rotation = [recognizer rotation];
[recognizer.view setTransform:CGAffineTransformRotate(recognizer.view.transform, rotation)];
[recognizer setRotation:0];
}
}
after add this delegate method
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
you can handle also pangesture using this method.
add pan gesture in to image.
self.panResizeGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(handlePanGestures:)];
imgPatSelect.userInteractionEnabled = YES;
[imgPatSelect addGestureRecognizer:self.panResizeGesture];
add this method to handle pan.
- (void) handlePanGestures:(UIPanGestureRecognizer*)recognizer{
CGPoint translation = [recognizer translationInView:self.view];
CGRect recognizerFrame = recognizer.view.frame;
recognizerFrame.origin.x += translation.x;
recognizerFrame.origin.y += translation.y;
// Check if UIImageView is completely inside its superView
if (CGRectContainsRect(self.view.bounds, recognizerFrame)) {
recognizer.view.frame = recognizerFrame;
}
// Else check if UIImageView is vertically and/or horizontally outside of its
// superView. If yes, then set UImageView's frame accordingly.
// This is required so that when user pans rapidly then it provides smooth translation.
else {
// Check vertically
if (recognizerFrame.origin.y < self.view.bounds.origin.y) {
recognizerFrame.origin.y = 0;
}
else if (recognizerFrame.origin.y + recognizerFrame.size.height > self.view.bounds.size.height) {
recognizerFrame.origin.y = self.view.bounds.size.height - recognizerFrame.size.height;
}
// Check horizantally
if (recognizerFrame.origin.x < self.view.bounds.origin.x) {
recognizerFrame.origin.x = 0;
}
else if (recognizerFrame.origin.x + recognizerFrame.size.width > self.view.bounds.size.width) {
recognizerFrame.origin.x = self.view.bounds.size.width - recognizerFrame.size.width;
}
}
// Reset translation so that on next pan recognition
// we get correct translation value
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}
I am trying to rotate a view , with UIRotationGestureRecognizer but the problem is the rotation's angle is not center of my view !! here is my code :
UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotate:)];
[rotationRecognizer setDelegate:self];
[self.view addGestureRecognizer:rotationRecognizer];
-(void)rotate:(id)sender {
if([(UIRotationGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
_lastRotation = 0.0;
return;
}
CGFloat rotation = 0.0 - (_lastRotation - [(UIRotationGestureRecognizer*)sender rotation]);
CGAffineTransform currentTransform = textViews.transform;
CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform,rotation);
_lastRotation = [(UIRotationGestureRecognizer*)sender rotation];
[textViews setTransform:newTransform];
}
// create and configure the rotation gesture
UIRotationGestureRecognizer *rotationGestureRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotationGestureDetected:)];
[rotationGestureRecognizer setDelegate:self];
[YOUR_OBJECT_HERE addGestureRecognizer:rotationGestureRecognizer];
// YOUR_OBJECT_HERE - can be any object that you want to rotate (e.g. textView as in your case)
- (void)rotationGestureDetected:(UIRotationGestureRecognizer *)recognizer
{
UIGestureRecognizerState state = [recognizer state];
if (state == UIGestureRecognizerStateBegan || state == UIGestureRecognizerStateChanged)
{
CGFloat rotation = [recognizer rotation];
[recognizer.view setTransform:CGAffineTransformRotate(recognizer.view.transform, rotation)];
[recognizer setRotation:0];
}
}
I've got it so far that I can move, scale and rotate all the objects, but the multiple objects all move together. I want them to move seperate. I guess I have to change the objectatIndex to 1, but it just crashes.
I've used the following code:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSArray *allTouches = [touches allObjects];
UITouch* t;
if([[event allTouches] count]==1){
if (CGRectContainsPoint([Birdie frame], [[allTouches objectAtIndex:0] locationInView:theimageView]) && CGRectContainsPoint([imageViewauto frame], [[allTouches objectAtIndex:0] locationInView:theimageView])) {
t=[[[event allTouches] allObjects] objectAtIndex:0];
touch1=[t locationInView:nil];
}
}else{
t=[[[event allTouches] allObjects] objectAtIndex:0];
touch1=[t locationInView:nil];
t=[[[event allTouches] allObjects] objectAtIndex:1];
touch2=[t locationInView:nil];
}
}
-(double)distance:(CGPoint)point1 toPoint:(CGPoint)point2
{
double deltaX, deltaY;
deltaX = point1.x - point2.x;
deltaY = point1.y - point2.y;
return sqrt(deltaX * deltaX + deltaY * deltaY);
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint currentTouch1;
CGPoint currentTouch2;
NSArray *allTouches = [touches allObjects];
UITouch* t;
float scale,rotation;
if([[event allTouches] count]==1){
t=[[[event allTouches] allObjects] objectAtIndex:0];
if (CGRectContainsPoint([Birdie frame], [[allTouches objectAtIndex:0] locationInView:theimageView]) && CGRectContainsPoint([imageViewauto frame], [[allTouches objectAtIndex:0] locationInView:theimageView]))
{
touch2=[t locationInView:nil];
Birdie.center=CGPointMake(Birdie.center.x+touch2.x-touch1.x,Birdie.center.y+touch2.y-touch1.y);
imageViewauto.center=CGPointMake(imageViewauto.center.x+touch2.x-touch1.x,imageViewauto.center.y+touch2.y-touch1.y);
touch1=touch2;
}
}
else if([[event allTouches] count]==2)
{
t=[[[event allTouches] allObjects] objectAtIndex:0];
currentTouch1=[t locationInView:nil];
t=[[[event allTouches] allObjects] objectAtIndex:1];
currentTouch2=[t locationInView:nil];
double distance1 = [self distance:currentTouch1 toPoint:currentTouch2];
double distance2 = [self distance:touch1 toPoint:touch2];
if (distance2 == 0)
{
//handle the case where distance is zero
}
else {
scale =distance1 / distance2;}
rotation=atan2(currentTouch2.y-currentTouch1.y, currentTouch2.x-currentTouch1.x)-atan2(touch2.y-touch1.y,touch2.x-touch1.x);
if(isnan(scale)){
scale=1.0f;
}
NSLog(#"rotation %f",rotation);
NSLog(#"scale %f",scale);
if (CGRectContainsPoint([Birdie frame], [[allTouches objectAtIndex:0] locationInView:theimageView]) && CGRectContainsPoint([imageViewauto frame], [[allTouches objectAtIndex:0] locationInView:theimageView]))
{
Birdie.transform=CGAffineTransformScale(Birdie.transform, scale,scale);
Birdie.transform=CGAffineTransformRotate(Birdie.transform, rotation);
imageViewauto.transform=CGAffineTransformScale(imageViewauto.transform, scale,scale);
imageViewauto.transform=CGAffineTransformRotate(imageViewauto.transform, rotation);
}
else // In case of scaling or rotating the background imageView
{
imageView.transform=CGAffineTransformScale(imageView.transform, scale,scale);
imageView.transform=CGAffineTransformRotate(imageView.transform, rotation);
}
touch1=currentTouch1;
touch2=currentTouch2;
}
}
First of all, an easy way to handle drag, scale and rotate is to use GestureRecognizers like the bellow one:
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(scale:)];
[pinchRecognizer setDelegate:self];
[self.view addGestureRecognizer:pinchRecognizer];
UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(rotate:)];
[rotationRecognizer setDelegate:self];
[self.view addGestureRecognizer:rotationRecognizer];
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(move:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[panRecognizer setDelegate:self];
[self.view addGestureRecognizer:panRecognizer];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapped:)];
[tapRecognizer setNumberOfTapsRequired:1];
[tapRecognizer setDelegate:self];
[self.view addGestureRecognizer:tapRecognizer];
To handle multiple UIImageViews you may use the position of touched points, you can use the bellow functions to do so:
- (CGPoint)locationInView:(UIView*)view;
- (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(UIView*)view;
According to the number of touched you can use either the first or second function, and then see if the touched point is inside the frame of considered UIImageView, for example for scaling you can do as what is show in bellow:
-(void)scale:(id)sender {
UIView * pinchView = [(UIPinchGestureRecognizer*)sender view];
CGPoint first_point = [sender locationOfTouch:0 inView:pinchView];
CGPoint second_point = [sender locationOfTouch:1 inView:pinchView];
if (CGRectContainsPoint(my_image_view.frame, first_point) && CGRectContainsPoint(my_image_view.frame, second_point)) {
[self.view bringSubviewToFront:pinchView];
if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
lastScale = 1.0;
return;
}
CGFloat scale = 1.0 - (lastScale - [(UIPinchGestureRecognizer*)sender scale]);
CGAffineTransform currentTransform = my_image_view.transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
[my_image_view setTransform:newTransform];
lastScale = [(UIPinchGestureRecognizer*)sender scale];}}
its working
-(void)scale:(id)sender {
if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
_lastScale = 1.0;
}
CGFloat scale = 1.0 - (_lastScale - [(UIPinchGestureRecognizer*)sender scale]);
CGAffineTransform currentTransform = self.transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
[self setTransform:newTransform];
_lastScale = [(UIPinchGestureRecognizer*)sender scale];
[self showOverlayWithFrame:self.frame];
}
-(void)rotate:(id)sender {
if([(UIRotationGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
_lastRotation = 0.0;
return;
}
CGFloat rotation = 0.0 - (_lastRotation - [(UIRotationGestureRecognizer*)sender rotation]);
CGAffineTransform currentTransform = self.transform;
CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform,rotation);
[self setTransform:newTransform];
_lastRotation = [(UIRotationGestureRecognizer*)sender rotation];
[self showOverlayWithFrame:self.frame];
}
-(void)move:(id)sender {
CGPoint translatedPoint = [(UIPanGestureRecognizer*)sender translationInView:self];
if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateBegan) {
_firstX = [self center].x;
_firstY = [self center].y;
}
translatedPoint = CGPointMake(_firstX+translatedPoint.x, _firstY+translatedPoint.y);
[self setCenter:translatedPoint];
[self showOverlayWithFrame:self.frame];
NSLog(#"after move x= %f y=%f " , _firstX,_firstY);
}