I have a scroll view that is the width of the screen but only about 70 pixels high. It contains many 50 x 50 icons (with space around them) that I want the user to be able to choose from. But I always want the scroll view to behave in a paged manner, always stopping with an icon in the exact center.
If the icons were the width of the screen this wouldn't be a problem because the UIScrollView's paging would take care of it. But because my little icons are much less than the content size, it doesn't work.
I've seen this behavior before in an app call AllRecipes. I just don't know how to do it.
Any ideas about how to get paging on a per-icon sized basis to work?
This is the only real solution to the problem.
When creating the scrollview, make sure you set this:
Then add your subviews to the scroller at an offset equal to their index * height of the scroller. This is for a vertical scroller:
If you run it now the views are spaced out, and with paging enabled they scroll on one at a time.
So then put this in your viewDidScroll method:
The frames of the subviews are still spaced out, we're just moving them together via a transform as the user scrolls.
Also, you have access to the variable p above, which you can use for other things, like alpha or transforms within the subviews. When p == 1, that page is fully being shown, or rather it tends towards 1.
I see a lot of solutions, but they are very complex. A much easier way to have small pages but still keep all area scrollable, is to make the scroll smaller and move the
scrollView.panGestureRecognizer
to your parent view. These are the steps:Reduce your scrollView size
Make sure your scroll view is paginated and does not clip subview
In code, move the scrollview pan gesture to the parent container view that is full width:
Try making your scrollview less than the size of the screen (width-wise), but uncheck the "Clip Subviews" checkbox in IB. Then, overlay a transparent, userInteractionEnabled = NO view on top of it (at full width), which overrides hitTest:withEvent: to return your scroll view. That should give you what you're looking for. See this answer for more details.
There is also another solution wich is probably a little bit better than overlaying scroll view with another view and overriding hitTest.
You can subclass UIScrollView and override its pointInside. Then scroll view can respond for touches outside its frame. Of course the rest is the same.
Old thread, but worth mentioning my take on this:
This way you can a) use the entire width of the scrollview to pan / swipe and b) be able to interact with the elements that are out of the scrollview's original bounds