Reza.Ab Reza.Ab - 1 month ago 13x
iOS Question

Why touchesbegan: never gets called on a UIView after UIPinchGestureRecognizer is used?

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;
[[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.
[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];

UIPinchGestureRecognizer*pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(handlePinch:)];
pinch.delegate =self;
[sV addGestureRecognizer:pinch];
- (void)handlePinch:(UIPinchGestureRecognizer *)recognizer{

if ([recognizer numberOfTouches] < 2)
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],
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;

ddb ddb

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