2

I have a horizontal paginated UIScrollView with a UIButton partially covering the scroll view.

Like this:

UIView
|
|- UIScrollView
|
|- UIButton

I want to make the UIButton to not trigger on tap-scroll-and-relase-above-the-button (I want the UIScrollView to scroll instead). I want the button to only respond to tap-and-release-without-moving.

Can this easy and quickly done? Or should I subclass the UIButton and override -touchesBegan:, etc., to manually pass the touches to the scrollView when appropriate?

Kanan Vora
  • 2,124
  • 1
  • 16
  • 26
Ricardo Sanchez-Saez
  • 9,466
  • 8
  • 53
  • 92

2 Answers2

1

After some additional research I found a reasonable solution. The problem here is that UIScrollView and UIButton are not in the same responder-chain hierarchy: the next responder for both is the parent UIView, so they don't send events to each other by default.

The solution would be to subclass UIButton and implement the

- (UIResponder *)nextResponder

method so it returns the UIScrollView.


An alternate solution is to make the UIButton a child of the UIScrollView. However, that doesn't work great if you want to keep the button at a fixed position regardless of cell scrolling.


It's somewhat annoying that there's no simpler way of doing this. :-)

Ricardo Sanchez-Saez
  • 9,466
  • 8
  • 53
  • 92
0

Okay then, try this. This sets the tap recognizer on the button to wait until the tap has ended, then tests to see if the touch ended in the UIButton.

UIButton * btn;
UITapGestureRecognizer * getTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(methodToPerformOnTap:)];
[btn addGestureRecognizer:getTap];

-(void) methodToPerformOnTap:(UITapGestureRecognizer *)sender {
    if ([sender state] == UIGestureRecognizerStateEnded)
    {
        CGPoint point = [sender locationInView:btn];
        if ( CGRectContainsPoint(btn.bounds, point) ) {

            // Point lies inside the bounds. HANDLE BUTTON TAP HERE.

        }
    }
}
Jack C
  • 1,044
  • 2
  • 12
  • 22