SanitLee SanitLee - 2 months ago 28
Objective-C Question

UITapGestureRecognizer blocks touch event for UIButton in subview

I believe I have an issue with UITapGestureRecognizer for dismissing keyboard when tapping in chatroom area preventing or blocking touch to the previewCancelButton. Here below are my relevant codes:

BaseTemplateVC.m

- (void)addDismissKeyboardGesture {

UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard:)];
tapGesture.cancelsTouchesInView = NO;
tapGesture.delegate = self;
self.view.tag = 111;
[self.view addGestureRecognizer:tapGesture];
}

- (void) dismissKeyboard:(id)sender {
UITapGestureRecognizer *gesture = sender;
UIView *view = gesture.view;
NSLog(@"%ld", (long)view.tag);
[self.view endEditing:YES];
}


ChatroomVC.m

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{

//Disallow recognition of tap gestures in the segmented control.
if (([touch.view isKindOfClass:[UIButton class]])) {
NSLog(@"noooooooo");
return NO;
}
return YES;
NSLog(@"yesssssss");
}


InputFunctionView.m

- (void)selectedSticker:(NSString *)stickerURLString {

/* Sticker preview subview */
stickerPreviewView = [[UIImageView alloc] initWithFrame:CGRectMake(0, -120, FrameWidth, 120)];
stickerPreviewView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5f];
stickerPreviewView.userInteractionEnabled = YES;
[self addSubview:stickerPreviewView];
[self bringSubviewToFront:stickerPreviewView];

/* Initialise previewCancelButton */
self.previewCancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
self.previewCancelButton.frame = CGRectMake(Main_Screen_Width-30, SpaceForItems-120, 20, 20);
[self.previewCancelButton setBackgroundImage:[UIImage imageNamed:@"btn_previewcancel.png"] forState:UIControlStateNormal];
[self.previewCancelButton setBackgroundImage:[UIImage imageNamed:@"btn_previewcancel.png"] forState:UIControlStateHighlighted];

[self.previewCancelButton addTarget:self action:@selector(cancelStickerPreviewButtonPressed:) forControlEvents:UIControlEventTouchUpInside];

[self addSubview: self.previewCancelButton];

}

/* Cancel sticker preview subview */
- (void)cancelStickerPreviewButtonPressed:(id)sender {

NSLog(@"cancel sticker preview");
[self.previewCancelButton removeFromSuperview];
[stickerPreviewView removeFromSuperview];

}


Now the previewCancelButton is correctly on right top corner of stickerPreviewView but unable to receive touch event to it. When I touch the button it shows "111" in the console and when I traced back I found BaseTemplateVC.m that contains addDismissKeyboardGesture method, so I believe this may cause the issue.

Anyone can guide me to some solutions. That'd be really appreciated. Thanks in advance.enter image description here

Progress: I have modified gestureRecognizer method in ChatroomVC.m so now it can ignore tap gesture on the button but the problem remains action for the button doesn't get fired.

Answer

I found a solution to this by using below code in GestureRecogniser delegate method:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
  if ([touch.view isDescendantOfView:IFView.stickerPreviewView]) {
     return NO;
  }
     return YES;
}

It specifies exactly what subview in this case IFView.stickerPreviewView is to return NO. Also in InputFunctionView, use this instead to add the subview:

[self.superview addSubview:_stickerPreviewView];