简体   繁体   中英

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. 在此处输入图片说明

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.

Just take a try with this, i guess it will work. Use the shouldReceiveTouch delegate method of gesture, and return NO when the touch.view is button class. So when it finds button It will discard the gesture and take button action.

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

    // Block the recognition of tap gestures in the button.
    if (([touch.view isKindOfClass:[UIButton class]])) {
       return NO;
    }

    return YES;
}

Here is the demo implementation : I have taken the button on main view of view controller in the story board.

- (void)viewDidLoad {
    [super viewDidLoad];

    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureClicked:)];
    tapGesture.delegate = self;
    [self.view addGestureRecognizer:tapGesture];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {

    // Disallow recognition of tap gestures in the segmented control.
    if (([touch.view isKindOfClass:[UIButton class]])) {
        return NO;
    }
    return YES;
}
- (IBAction)btnTestClicked:(UIButton *)sender {
    NSLog(@"test button click");
}

- (void)tapGestureClicked:(UIGestureRecognizer *)recog
{
    NSLog(@"tap gesture clicked");
}

Hope it helps. Happy coding ...

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM