I’m creating an image Based app and I want the images that are displayed to be rotated/moved/scaled within the UIView that i’ve created. I followed a useful tutorial online on how to implement UIGestures and I’ve got the hang of using them I just need to understand the code behind them a bit more so I can retain the gestures within this UIView. here is the Code:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
image = [info objectForKey:@"UIImagePickerControllerOriginalImage"];
layoutOne = [[UIView alloc] initWithFrame:CGRectMake(95.0, 107.0, 578, 682)];
theImageView = [[UIImageView alloc] initWithFrame:[layoutOne frame]];
[theImageView setImage:image];
theImageView.userInteractionEnabled = TRUE;
[layoutOne addSubview:theImageView];
takePhoto.hidden = YES;
theImageView.clipsToBounds = YES;
UIPinchGestureRecognizer *pinchRecognizer = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scale:)];
[pinchRecognizer setDelegate:self];
[theImageView addGestureRecognizer:pinchRecognizer];
UIRotationGestureRecognizer *rotationRecognizer = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotate:)];
[rotationRecognizer setDelegate:self];
[theImageView addGestureRecognizer:rotationRecognizer];
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(move:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
[panRecognizer setDelegate:self];
[theImageView addGestureRecognizer:panRecognizer];
UITapGestureRecognizer *deleteButton = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(delButton:)];
[deleteButton setNumberOfTapsRequired:2];
[deleteButton setDelegate:self];
[theImageView addGestureRecognizer:deleteButton];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)];
[tapRecognizer setNumberOfTapsRequired:1];
[tapRecognizer setDelegate:self];
[tapRecognizer requireGestureRecognizerToFail:deleteButton];
[theImageView addGestureRecognizer:tapRecognizer];
[self.view addSubview:theImageView];
}
NOTE
UIImage *image;
UIImageView *theImageView;
UIView *layoutOne;
Those are my declared Gesture Recognisers and below is another part of the tutorial I followed to get them to do their jobs:
-(void)scale:(id)sender {
NSLog(@"See a pinch gesture");
[self.view bringSubviewToFront:[(UIPinchGestureRecognizer*)sender view]];
if([(UIPinchGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
lastScale = 1.0;
return;
}
CGFloat scale = 1.0 - (lastScale - [(UIPinchGestureRecognizer*)sender scale]);
CGAffineTransform currentTransform = [(UIPinchGestureRecognizer*)sender view].transform;
CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, scale, scale);
[[(UIPinchGestureRecognizer*)sender view] setTransform:newTransform];
lastScale = [(UIPinchGestureRecognizer*)sender scale];
}
-(void)rotate:(id)sender {
NSLog(@"See a rotate gesture");
[self.view bringSubviewToFront:[(UIRotationGestureRecognizer*)sender view]];
if([(UIRotationGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
lastRotation = 0.0;
return;
}
CGFloat rotation = 0.0 - (lastRotation - [(UIRotationGestureRecognizer*)sender rotation]);
CGAffineTransform currentTransform = [(UIPinchGestureRecognizer*)sender view].transform;
CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform,rotation);
[[(UIRotationGestureRecognizer*)sender view] setTransform:newTransform];
lastRotation = [(UIRotationGestureRecognizer*)sender rotation];
}
-(void)move:(id)sender {
NSLog(@"See a move gesture");
[[(UITapGestureRecognizer*)sender view] layer];//removeAllAnimations];
[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+translatedPoint.y);
[[sender view] setCenter:translatedPoint];
if([(UIPanGestureRecognizer*)sender state] == UIGestureRecognizerStateEnded) {
CGFloat finalX = translatedPoint.x + (.35*[(UIPanGestureRecognizer*)sender velocityInView:self.view].x);
CGFloat finalY = translatedPoint.y + (.35*[(UIPanGestureRecognizer*)sender velocityInView:self.view].y);
if(UIDeviceOrientationIsPortrait([[UIDevice currentDevice] orientation])) {
if(finalX < 0) {
finalX = 0;
}
else if(finalX > 768) {
finalX = 768;
}
if(finalY < 0) {
finalY = 0;
}
else if(finalY > 1024) {
finalY = 1024;
}
}
else {
if(finalX < 0) {
finalX = 0;
}
else if(finalX > 1024) {
finalX = 768;
}
if(finalY < 0) {
finalY = 0;
}
else if(finalY > 768) {
finalY = 1024;
}
}
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:.35];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[[sender view] setCenter:CGPointMake(finalX, finalY)];
[UIView commitAnimations];
}
}
Sorry about the long lines of the code I just want to make sure that you understand exactly what I’m trying to achieve. I want to better understand the Maths thats going on within mainly the -(void)move:(id)sender so I might be able to stop the UIImage/UIImageView from moving outside the UI subview (layoutOne) that I’ve created. If you might be able help me that would be really appreciated! Thanks.
I figured out how to do this with the method I used above. It was really easy once I figured out what I needed to do. If your using this method above yourself, all you need to do is make sure the
UIViewyour using in this case mine is calledlayoutOne. In themove:,rotate:,scale:methods you need to add inlayoutOne.clipsToBounds = YES;making sure that it’s not within any of theif,else if,elsestatements. This should keep the image you wish to interact with doesn’t move outside theUIViewinstead if it touches the bounds of the View those parts of the image will not appear. Simples!