3
votes

Example:

You have a UIScrollView with scrollEnabled = NO. After user pans a certain distance, you want the scroll view to start scrolling.

When finger goes down on screen and I disable scrolling, the scroll view is dead until the finger is lifted. Enabling scrolling in middle of a pan doesn't cause it to start.

I suspect it is because UIScrollView will decide to ignore the touch sequence if it was scrollEnabled=NO during its internal touchesBegan:withEvent: (or its private pan gesture recognizer).

How would you trick it into starting to scroll natively (with bounce effect) in the middle of a touch sequence?

Reason: For a simple UIKit based game that requires this mechanic.

1
Have a look at 2012 or 2013 WWDC scroll view sessions. They detail how to steal a pan gesture recogniser from an offscreen scroll view. The tech may help.Warren Burton

1 Answers

0
votes

Okay, this still needs a little bit of tweaking to handle scrolling again after the first scroll has stopped, but I think the key to what you're trying to achieve is to implement the UIScrollViewDelegate method scrollViewDidScroll:. From here, you can save the starting content offset of the scroll view, and compare the scroll view's current offset to the starting offset added to the y translation of the scroll view's pan gesture recognizer.

The code below successfully doesn't allow scrolling to start until the user has panned at least 100 pts. Like I said, this needs a little tweaking, but should be enough to get you going.

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self setStartingOffset:CGPointMake(0.0, -1.0)];
}


- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    if (self.startingOffset.y < 0.0) {
        [self setStartingOffset:scrollView.contentOffset];
    }else{
        static CGFloat min = 100.0;
        CGFloat yTranslation = fabs([scrollView.panGestureRecognizer translationInView:scrollView].y);

        if (yTranslation < self.startingOffset.y + min) {
            [scrollView setContentOffset:self.startingOffset];
        }else{
            if (self.startingOffset.y >= 0.0) {
                [self setStartingOffset:CGPointMake(0.0, -1.0)];
            }
        }
    }
}