Search code examples
uitableviewuiscrollviewuibuttonuirespondertouch-up-inside

UIButton is not receiving actions behind UIScrollView


I put UIButton inside UITableViewCell in UITableView that is behind UIScrollView. I subclassed UIScrollView to forward touches to UITableView.

So method from UITableViewDelegate didSelectRow is calling properly. The problem is that UIButton inside table cell is not receiving TouchUpInside actions.

How can I solve this problem without deleting ScrollView over TableView?

EDIT:

I resolved this issue by detecting which view will receive touch. Here's the code:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UIView *hitView = [self hitTest:[(UITouch*)[[touches allObjects] objectAtIndex:0] locationInView:self] withEvent:event];
    if ([hitView isKindOfClass:[UIButton class]]) {
        [(UIButton*)hitView sendActionsForControlEvents:UIControlEventTouchUpInside];
    }
    [super touchesBegan:touches withEvent:event];
}

Solution

  • If you want to enable actions for bouth objects - UIScrollView and UIButton you should to implement custom hit test mechanism for ScrollView.

    In your UIScrollView subclass override - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event method to make views behind ScrollView available for getting events.

    - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
    {
        return __touchesEnabled;
    }
    
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        _touchesEnabled = NO;
        UIWindow *window = [UIApplication sharedApplication].delegate.window;
        for(UITouch *touch in touches) {
           CGPoint point = [touch locationInView:self];
           point = [window convertPoint:point fromView:self];
           UIView *view = [window hitTest:point withEvent:event];
           [view touchesBegan:touches withEvent:event];
        }  
        _touchesEnabled = YES;
    }
    

    It works for me