13
votes

I have a UIScrollView's paging enabled and set its clipToBounds = NO so that I can see outside current page.

What I want is to enable the user to scroll the UIScrollView on its entire visible area, not only the part of current page.

How can I implement this?

P.S. According to Apple's documentation (https://developer.apple.com/documentation/uikit/uiscrollview), if the value of pagingEnabled property is YES, the scroll view stops on multiples of the scroll view’s bounds when the user scrolls.

This means I cannot just resize the UIScrollView to get what I want without compromising paging functionality, right?

3

3 Answers

14
votes

Put the scrollview into a uiview and disable clipsToBounds of the scrollview. the scrollview must be the size you want for paging. you will see the content outside of the scrollview but paging wil still be the same. You can activate clipsToBounce for the outside view to limit the size of the scrollview.

Overwrite the hitTest of the view to redirect the touches to the scrollview... then you will be able to also scroll by touching outside of the scrollview.

7
votes

Why don't you resize your scrollView so it'll fit the area you need?

Not sure if it'll help, but try to override UIScrollView pointInside method

- (BOOL) pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    CGRect newBounds = self.bounds;
    newBounds = CGRectInset(bounds, 0, -100.0f);
    return CGRectContainsPoint(newBounds, point);
}
1
votes

2019 syntax example:

class LargerScrollArea: UICollectionView {

    // Example, say this is the left half of the screen, but, we wish to be
    // able to scroll on the whole width of the screen

    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {

        if isUserInteractionEnabled == false { return nil }

        let extraOnRight = bounds.width
        let largerBounds = bounds.inset(by:
                UIEdgeInsets(top: 0, left: 0, bottom:0, right: -extraOnRight))
        if largerBounds.contains(point) {
            return self
        }
        else {
            return nil
        }
    }
}

(Collection view, table view, all the same.)