5

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];
}
Kuboslav
  • 75
  • 6
  • Would like to share your method for capturing didSelect tableView delegate's method for a tableview behind a scrollview ? Thx a lot ! – Pete Feb 04 '13 at 14:41
  • There's nothing special in method -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath. Calling of his method is OK even when tableView is behind scrollView. – Kuboslav Feb 04 '13 at 15:10
  • Weird because I can scroll my UIScrollView but can't call -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath – Pete Feb 04 '13 at 15:33
  • I forgot... I overided methods touchesBegan: touchesEnded: touchesMoved: touchesCancelled: in my scrollView and I'm sending touches to tableView behind. It looks like this: - (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event { [self.nextResponder touchesEnded:touches withEvent:event]; [self.behindTable touchesEnded:touches withEvent:event]; [super touchesEnded:touches withEvent:event]; } – Kuboslav Feb 05 '13 at 15:45

2 Answers2

4

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

Alex
  • 54
  • 2
  • 1
    If I do this the buttons receive the event but now the views inside the scrollview don't, and I can't scroll. – htafoya Dec 20 '12 at 18:01
0

Since you have added your scroll view over the UIButton, all the touch actions will not be passed to the button.

    [yourScrollView setUserInteractionEnabled:NO];

This may solve your problem.

Ramaraj T
  • 5,184
  • 4
  • 35
  • 68