Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIView on top of UIScrollview, pass through only scrolls, not taps

I have a UITableview with a subclass of UIVIew on top of a section of the table, like so:

-uitable-- |--uiview-| || || || || |---------| | | | | -----------

The view has the same superview as the tableview, but covers the tableview partially. There are a few buttons on the UIView. I want the user to be able to scroll on the view and subsequently move the tableview (as if he were scrolling on the table). But, if he taps a button on the view, I want that tap to register on the view, not get sent down to the tableview. Right now, I am overriding the view's - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event method to always return NO, which works for the scrolling but has the effect of sending all touches down to the tableview, rendering my buttons ineffective. Is there any way for me to pass down swipe/pan gestures to the tableview but keep the tap gestures?

Thanks,

like image 843
Kyle Rosenbluth Avatar asked Apr 27 '14 20:04

Kyle Rosenbluth


1 Answers

Instead of always returning NO from pointInside, check to see if the point intersects any of your UIButton subviews - and return YES if it does.

- (BOOL) pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    for ( UIView* sv in self.subviews )
    {
        if ( CGRectContainsPoint( sv.frame, point) )
            return YES;
    }

    return NO;
}

EDIT: alternate solution

Per your comment you'd like the user to begin scrolling the UITableView with a touch-down on one of the subview buttons. To make this work you'll need to make the UIView that contains your buttons a subview of the UITableView.

By doing this the UIView will then begin to scroll along with the UITableViewCells. To prevent this you need to adjust the frame as scrolling happens, or possibly lock it in place using constraints.

- (void) viewDidLoad
{
    [super viewDidLoad];

    // instantiate your subview containing buttons.  mine is coming from a nib.
    UINib* n = [UINib nibWithNibName: @"TSView" bundle: nil];
    NSArray* objs = [n instantiateWithOwner: nil options: nil];
    _tsv = objs.firstObject;

    // add it to the tableview:
    [self.tableView addSubview: _tsv];
}

// this is a UIScrollView delegate method - but UITableView IS a UIScrollView...
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    [scrollView bringSubviewToFront:_tsv];
    CGRect fixedFrame = _tsv.frame;
    fixedFrame.origin.y = 100 + scrollView.contentOffset.y;
    _tsv.frame = fixedFrame;
}
like image 143
TomSwift Avatar answered Sep 18 '22 01:09

TomSwift