I have a UIScrollView
with horizontal pagination - similar to the weather app. Under certain circumstances, I want to prevent the user from scrolling horizontally. Simply disabling the scrolling is a little jarring - I would prefer to duplicate the experience of scrolling past the last page - a little scrolling is permitted, but since there is no more content, the scrollview bounces back.
How might I go about implementing this? Should I be changing the contentSize of the ScrollView? How do I set up the pagination so that there is effectively one 'page' but there is still content displayed to the immediate left and right?
In order to always make the UIScrollView
bounce, even with just one page, add the following line:
[self.scrollView setAlwaysBounceHorizontal:YES];
In addition to my comment about shrinking the contentSize
, of course.
EDIT:
OK, let me first explain want we want to achieve. The User is scrolling happily between the pages in the UIScrollView
, and suddenly, we want the UIScrollView
to stick to the current page, which may or may not be the first page.
Our UIScrollView
has the pages laid out, with each page represented by a single UIView
or it's subclasses (it may have subviews itself):
Now, to perform the task explained, here is the code:
CGFloat pageWidth = _scrollView.bounds.size.width;
int currentPage = (_scrollView.contentOffset.x / pageWidth);
[_scrollView setContentSize:CGSizeMake(pageWidth, _scrollView.contentSize.height)];
// move each page to the left:
for (UIView* page in _scrollView.subviews) {
[page setFrame:CGRectOffset(page.frame, -currentPage * pageWidth, 0)];
}
NOTE: If you have a complicated view hierarchy, just wrap it in a UIView
that has a bounds size equal to the _scrollView.contentSize
with all the pages. The rest I leave it as an exercise for the reader (I always wanted to say that xD)
Mazyod's answer above is probably the best one, but I had a lot of trouble returning the views to their original location and resizing the contentSize
in a way that is hidden from the user. I used the following approach instead.
I simply create a new scrollview, with a limited size, and lay it over the top of my existing one. I move the three views (the one being used and those either side) into this temporary scrollview, adjusting their origin as per Mazyod's answer.
When I need to revert, I simply move the views back into the real scrollview and remove the temporary one.
Not as efficient, but a viable alternative.