Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass certain touches through UIScrollView to underlying views

I've got a view that has two subviews:

  1. Subview A, a UIView (contains other views, which contain UIButtons, views with gesturerecognizer ...)
  2. Subview B, a UIScrollView (contains some views, but has transparent regions).

The scrollview is on top of Subview A and has the full device width/height. I want the user to be able to interact - through the transparent regions - with all those buttons and gesture reconizers below the scrollview, while still being able to scroll (so passing on the hittest is out).

Seems like an easy enough task, but I can't get it to work. The scrollview is always blocking all touches.

Any idea how I would accomplish that? Thanks!

like image 786
René Avatar asked Feb 03 '14 15:02

René


2 Answers

You should subclass the UIScrollView and overwrite the following method:

-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

If this method returns NO the scrollview will be "transparent" for touch events.

As you want the scrollview to be "transparent" for touch events only if the touch is in a transparent area of your scrollview, your implementation should look like:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
     return ![self isPointInsideATransparentRegion:point]; //you need to implement isPointInsideATransparentRegion to check whether the point touched is in a transparent region or not
}
like image 96
tanzolone Avatar answered Nov 04 '22 04:11

tanzolone


I've somewhat solved this now by adding the view that's supposed to be below the scrollview to the scrollview as the first subview, and shifting its position in scrollViewDidScroll:

-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
    [self updateBottomViewPosition];
}

- (void)updateBottomViewPosition {
    CGPoint contentOffset = _mainScrollView.contentOffset;

    CGFloat y = MAX(contentOffset.y, 0);

    CGRect frame = _bottomPage.frame;
    if (y != frame.origin.y) {
        frame.origin.y = y;
        _leadPage.frame = frame;
    }
}

This works, but it's probably not as elegant as possible.

like image 2
René Avatar answered Nov 04 '22 03:11

René