34

I have a horizontal scroll view with a line of buttons. The scroll view will not scroll unless I do an extremely fast swipe.

If I set the buttons to userInteractionEnabled = NO, then the scrolling works as expected, but of course, then the buttons don't work at all.

This app worked fine in iOS 7 and before. It seems to be a iOS 8 "feature". I did notice that I can catch the button's drag event, but I don't know how to redirect it back to the scrollView.

I'm thinking I'll need to replace my buttons with UIViews and manage the events myself but I'd be grateful if someone has other ideas or solutions.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Mike M
  • 4,358
  • 1
  • 28
  • 48
  • I don't have a solution yet but I just noticed I have the exact same issue. Will post a solution when I find one. – Ben Kane Sep 12 '14 at 19:19
  • FWIW, I rewrote the buttons to be UILabels and just managed with a UITapGestureRecognizer. There are some comments on the Apple forums with regards to this bug under the iOS8 beta category. – Mike M Sep 16 '14 at 15:07
  • Oops, I did find a solution, but forgot to post. Will post a little `UIScrollView` subclass in case you want to simplify what you did. – Ben Kane Sep 17 '14 at 21:36

5 Answers5

39

I found that in iOS 8, the UIScrollView's underlying UIPanGestureRecognizer is not respecting the UIScrollView's delaysContentTouches property. I consider this an iOS 8 bug. Here's my workaround:

theScrollView.panGestureRecognizer.delaysTouchesBegan = theScrollView.delaysContentTouches
lifjoy
  • 2,158
  • 21
  • 19
24

I've had this problem with a UITableView which has custom UITableViewCells with UIButtons on it. I put this in my UITableview class.

- (BOOL)touchesShouldCancelInContentView:(UIView *)view {
    return YES;
}

Solved my problem.

EDIT: Just to clearify, you can create a subclass of UIScrollview and add this to solve the problem.

Daniel Åkesson
  • 1,330
  • 1
  • 12
  • 21
10

This hack works for me:

UITapGestureRecognizer *nothingTap = [[UITapGestureRecognizer alloc] init];
nothingTap.delaysTouchesBegan = YES;
[_scrollView addGestureRecognizer:nothingTap];

credit: https://devforums.apple.com/thread/241467

daihovey
  • 3,485
  • 13
  • 66
  • 110
9

I made a subclass of UIScrollView to fix this issue. You only need this method in it:

- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
{
    UITouch *touch = [touches anyObject];

    if(touch.phase == UITouchPhaseMoved)
    {
        return NO;
    }
    else
    {
        return [super touchesShouldBegin:touches withEvent:event inContentView:view];
    }
}

Then just remember to set the class to your subclass in the storyboard if you're using one and you're good to go.

Ben Kane
  • 9,331
  • 6
  • 36
  • 58
  • Fixed mine too -- with a UISegmentedControl embedded in the scroll view. Many thanks! – Mickaël Sep 18 '14 at 11:14
  • 2
    I tried that, and it fixed the UIScrollView, but sometimes my buttons aren't responding on the first touch, did anyone else noticed that same behavior? – Leonardo Sep 18 '14 at 17:52
  • @Leonardo yep, noticing the same thing - so the solution above doesnt really solve the problem. Might have to, annoyingly, change all the buttons to views. – daihovey Sep 21 '14 at 04:03
0

I have same issue and I solved it by creating a subclass of UIScrollView and set it's cancelContentTouches value to TRUE and its working fine.

- (BOOL)touchesShouldCancelInContentView:(UIView *)view {
       return YES;
}

Hope it will work for you.

byJeevan
  • 3,728
  • 3
  • 37
  • 60
Urmi
  • 344
  • 1
  • 14