Tuesday, October 18, 2011

UIGestureRecognizers - UIPanGestureRecognizer - UIPinchGestureRecognizer Part 2

I wrote the piece about how to use UIPanGestureRecognizer here, but I skipped commenting which part do what. So here it goes.

//Last post, I forgot to add in the protocol that the class has to conform to which is UIGestureRecognizerDelegate
//So your header file will have something like this
@interface MyView : UIView

//At the header file, just need to write these few lines of code
UIPanGestureRecognizer * panGesture;
UIPinchGestureRecognizer *pinchGesture;

@property(nonatomic, retain) UIPanGestureRecognizer * panGesture;
@property(nonatomic, retain) UIPinchGestureRecognizer *pinchGesture;

//At your implementation file, these few lines of code should get your GestureRecognizer going
panGesture = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureMoveAround:)] autorelease];
[panGesture setMaximumNumberOfTouches:2];
[panGesture setDelegate:self];

//The pinch gesture
pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scalePiece:)];
[pinchGesture setDelegate:self];
[piece addGestureRecognizer:pinchGesture];

//Down here, we have the UIView that we want to pan around with. Here is a little tips, when you are working with UIImage and want to pan or pinch them around. You may want to add them to a UIView before doing so. Because I was having very peculiar behavior adding gesture recognizer to UIImage directly.
[dragView addGestureRecognizer:panGesture];

-(void)panGestureMoveAround:(UIPanGestureRecognizer *)gesture;
UIView *piece = [gesture view];

//We pass in the gesture to a method that will help us align our touches so that the pan and pinch will seems to originate between the fingers instead of other points or center point of the UIView
[self adjustAnchorPointForGestureRecognizer:gesture];

if ([gesture state] == UIGestureRecognizerStateBegan || [gesture state] == UIGestureRecognizerStateChanged) {

CGPoint translation = [gesture translationInView:[piece superview]];
[piece setCenter:CGPointMake([piece center].x + translation.x, [piece center].y+translation.y*0.1)];
[gesture setTranslation:CGPointZero inView:[piece superview]];
}else if([gestureRecognizer state] == UIGestureRecognizerStateEnded)
//Put the code that you may want to execute when the UIView became larger than certain value or just to reset them back to their original transform scale

- (void)pinchGestureMoveAround:(UIPinchGestureRecognizer *)gestureRecognizer
[self adjustAnchorPointForGestureRecognizer:gestureRecognizer];

if ([gestureRecognizer state] == UIGestureRecognizerStateBegan || [gestureRecognizer state] == UIGestureRecognizerStateChanged) {
[gestureRecognizer view].transform = CGAffineTransformScale([[gestureRecognizer view] transform], [gestureRecognizer scale], [gestureRecognizer scale]);
[gestureRecognizer setScale:1];
}else if([gestureRecognizer state] == UIGestureRecognizerStateEnded)
//The reset works much different here, where applying transform to CGAffineTransformIdentity doesn't work well. You may need to rescale UIView back using setRect function.

- (void)adjustAnchorPointForGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer {
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;

1 comment:

  1. [...] post here UIGestureRecognizers – UIPanGestureRecognizer – UIPinchGestureRecognizer – Part 2 iOS Human Interface [...]