I have to perform all the gesture on my imageview at a time, means user can move imageview on single tap at a time on double tap also zooming and rotation possible.Now i am found this methods to perform multiple gesture but unable to perform zoom and roation.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
Before i am applied UIPinchGestureRecognizer,UIRotationGestureRecognizer and UIPanGestureRecognizer but it handle only one gesture at a time.Please help me to solve this or give me any other better option if possible.
UIPinchGestureRecognizer *pinchGesture = ... //initialize
pinchGesture.delegate = self;
//same for rotation gesture
//and then implement delegate method
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
Set the gesture like this.
self.view.multipleTouchEnabled=YES;
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(moveViewWithGestureRecognizer:)];
panGestureRecognizer.delegate=self;
[self.sub_View addGestureRecognizer:panGestureRecognizer];
UIRotationGestureRecognizer *rotationGestureRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:#selector(handleRotationWithGestureRecognizer:)];
rotationGestureRecognizer.delegate=self;
[self.sub_View addGestureRecognizer:rotationGestureRecognizer];
UIPinchGestureRecognizer *pinchGestureRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(handlePinchWithGestureRecognizer:)];
pinchGestureRecognizer.delegate=self;
[self.sub_View addGestureRecognizer:pinchGestureRecognizer];
[self.imageView setUserInteractionEnabled:YES];
Handle the action
-(void)handlePinchWithGestureRecognizer:(UIPinchGestureRecognizer *)pinchGestureRecognizer{
[self.superImage_View setAlpha:0.5];
if (pinchGestureRecognizer.state == UIGestureRecognizerStateEnded) {
[self.superImage_View setAlpha:1.0];
}
self.imageView.transform = CGAffineTransformScale(self.imageView.transform, pinchGestureRecognizer.scale, pinchGestureRecognizer.scale);
pinchGestureRecognizer.scale =1.0;
}
-(void)handleRotationWithGestureRecognizer:(UIRotationGestureRecognizer *)rotationGestureRecognizer{
[self.superImage_View setAlpha:0.5];
if (rotationGestureRecognizer.state == UIGestureRecognizerStateEnded) {
[self.superImage_View setAlpha:1.0];
}
self.imageView.transform = CGAffineTransformRotate(self.imageView.transform, rotationGestureRecognizer.rotation);
rotationGestureRecognizer.rotation = 0.0;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
-(void)moveViewWithGestureRecognizer:(UIPanGestureRecognizer *)panGestureRecognizer{
//CGPoint touchLocation = [panGestureRecognizer locationInView:self.sub_View];
// self.imageView.center = touchLocation;
[self.superImage_View setAlpha:0.5];
CGPoint translation = [panGestureRecognizer translationInView:self.view];
self.imageView.center = CGPointMake(self.imageView.center.x + translation.x,
self.imageView.center.y + translation.y);
[panGestureRecognizer setTranslation:CGPointMake(0, 0) inView:self.view];
if (panGestureRecognizer.state == UIGestureRecognizerStateEnded) {
CGPoint velocity = [panGestureRecognizer velocityInView:self.view];
CGFloat magnitude = sqrtf((velocity.x * velocity.x) + (velocity.y * velocity.y));
CGFloat slideMult = magnitude / 200;
// NSLog(#"magnitude: %f, slideMult: %f", magnitude, slideMult);
float slideFactor = 0.1 * slideMult; // Increase for more of a slide
CGPoint finalPoint = CGPointMake(self.imageView.center.x + (velocity.x * slideFactor),
self.imageView.center.y + (velocity.y * slideFactor));
finalPoint.x = MIN(MAX(finalPoint.x, 0), self.view.bounds.size.width);
finalPoint.y = MIN(MAX(finalPoint.y, 0), self.view.bounds.size.height);
[UIView animateWithDuration:slideFactor*2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.imageView.center = finalPoint;
} completion:nil];
[self.superImage_View setAlpha:1.0];
}
}
Related
I'm developing a drawing app which lets user to draw a UIbezierpath on a UIView (InsideView) subviewed by it's superView (self.view). I'm using conventional drawing codes in the InsideView like touchesBegan:, touchesMoved:, touchesEnded:and I'm handling pinch zoom code handlePinch:(UIPinchGestureRecognizer *)recognizer: inside the viewController class (which is InsideView's superView).
When I draw first, I can do the pinch zoom after it but when I do the pinch zoom first, the drawing code (touchesBegan etc) doesn't get called after UIPinchGestureRecognizer is fired and it doesnt draw anything on InsideView. What am I doing wrong? Thanks in advance.
//Code in the InsideView (which is a UIView subclass and is a subview for self.view)
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
path = [UIBezierPath bezierPath];
[path setLineWidth:7.0];
pointsArray = [NSMutableArray array];
finish = NO;
}
return self;
}
-(void)drawRect:(CGRect)rect{
[[UIColor redColor] setStroke];
[path stroke];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self];
[path moveToPoint:p];
[pointsArray addObject:[NSValue valueWithCGPoint:p]];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGPoint p = [touch locationInView:self];
[path addLineToPoint:p];
[self setNeedsDisplay];
[pointsArray addObject:[NSValue valueWithCGPoint:p]];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
[path closePath];
//Smoothing the path.
path.miterLimit=-10;
[self setNeedsDisplay];
finish = YES;
}
//Code in the viewController (InsideView's superView)
- (void)viewDidLoad {
[super viewDidLoad];
InsideView* sV = [InsideView new];
[sV setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[self.view addSubview:sV];
//Pinch
UIPinchGestureRecognizer*pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:#selector(handlePinch:)];
pinch.delegate =self;
[sV addGestureRecognizer:pinch];
}
- (void)handlePinch:(UIPinchGestureRecognizer *)recognizer{
if ([recognizer numberOfTouches] < 2)
return;
if (recognizer.state == UIGestureRecognizerStateBegan) {
lastScale = 1.0;
lastPoint = [recognizer locationInView:self.view];
}
// Scale
CGFloat scale = 1.0 - (lastScale - recognizer.scale);
[sV.layer setAffineTransform:
CGAffineTransformScale([sV.layer affineTransform],
scale,
scale)];
lastScale = recognizer.scale;
// Translate
CGPoint point = [recognizer locationInView:self.view];
[sV.layer setAffineTransform:
CGAffineTransformTranslate([sV.layer affineTransform],
point.x - lastPoint.x,
point.y - lastPoint.y)];
lastPoint = [recognizer locationInView:self.view];
}
-(void)handlePinchWithGestureRecognizer:(UIPinchGestureRecognizer *)pinchGestureRecognizer{
sV.transform = CGAffineTransformScale(sV.transform, pinchGestureRecognizer.scale, pinchGestureRecognizer.scale);
pinchGestureRecognizer.scale = 1.0;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
return YES;
}
I've developed a UIViewController where I used them together without any problem,s maybe a solution could be to move this logic from UIView to the UIViewController. So at viewDidLoad you can define the pinch recognizer like this
UIPinchGestureRecognizer* pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:#selector(handlePinch:)];
[self.view addGestureRecognizer:pinch];
of course also the method handlePinch: should be moved to the UIViewController, together with touchesBegan:withEvent:,
touchesMoved:withEvent:, touchesEnded:withEvent: methods
what you should change in these methods is that you should change
self
to
self.yourSpecificCurrentUIView
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:
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];
}
I want to create a collapsing animated UISlider. Basicly, the slider will the size of the thumbimage until it is touched at which point it expands to full size while it is being changed. After the value is changed and the slider is let go, the slider will collapse back to the original size (the size of the thumbimage).
I tried working with touchesBegan and touchesEnd but this didn't get me very far.
So far i've subclassed UISlider and overrode the beginTrackingWithTouch and endTrackingWithTouch. This code kind of accomplishes the collapsing effect (Without the animation of course) but the thumb slider doesn't change anymore. Any ideas on how best to do this?
#import "CollapsingUISlider.h"
#implementation CollapsingUISlider
/*-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
//self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width * 4.0f, self.frame.size.height);
[super touchesBegan:touches withEvent:event];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
// self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width * 0.25f, self.frame.size.height);
[super touchesEnded:touches withEvent:event];
}*/
-(BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, 400, self.frame.size.height);
return YES;
}
-(void)endTrackingWithTouch:(UITouch*)touch withEvent:(UIEvent *)event {
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, 20, self.frame.size.height);
}
-(BOOL) continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, 400, self.frame.size.height);
return self.tracking;
}
#end
I ended up doing something like this:
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(move:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[platformView addGestureRecognizer:panRecognizer];
-(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, firstY+translatedPoint.y);
[[sender view] setCenter:translatedPoint];
if (platformView.center.y < platformCenter.y - offset) {
platformView.center = CGPointMake(platformCenter.x,platformCenter.y-offset);
((UIPanGestureRecognizer*)sender).enabled = NO;
} else if (platformView.center.y > platformCenter.y) {
platformView.center = CGPointMake(platformCenter.x,platformCenter.y);
((UIPanGestureRecognizer*)sender).enabled = NO;
}
}
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);
}