31

What's the simplest way to have a scroll view (with pagingEnabled set to YES) have a page width set to something other than the scroll view's bounds?

Let me give an example. Suppose I have a scroll view with 10 items, each 150 pixels wide, and my scroll view is 300 pixels wide. If I start with views 1 and 2 visible and scroll horizontally to the right, I want the next "page" to show items 2 and 3. If I scroll one more page to the right, I would see items 3 and 4.

Has anyone done this? If not, what strategy would you use?

Mike McMaster
  • 7,573
  • 8
  • 37
  • 42

5 Answers5

44

Alexander Repty just blogged about this very topic: http://blog.proculo.de/archives/180-Paging-enabled-UIScrollView-With-Previews.html. Short answer: it's not as simple as just changing the width of the 'page', but it's not too hard.

Ben Gottlieb
  • 85,404
  • 22
  • 176
  • 172
  • I've seen this approach mentioned elsewhere and tried it, but unfortunately I don't think it does what I want. I need more than to see the edges of the surrounding items - In my case, I need to have two items fully on screen. This approach unfortunately didn't work too well for me, especially on the very leftmost/rightmost edges. – Mike McMaster Feb 13 '10 at 01:48
  • 7
    Just make your scrollview 150px wide, but turn off clipping. Put the whole thing inside a view that's 300 px wide, and turn ON clipping for it. – Ben Gottlieb Feb 13 '10 at 04:44
  • Thanks, Ben. As I mentioned in my comment on Alexander's answer, this definitely put me on the right path. – Mike McMaster Feb 18 '10 at 06:06
  • 1
    Be sure to make note of "digdog"'s comment on the blog post, to make sure it works when you've got subviews that you need to be able to interact with. – Kristofer Sommestad Feb 23 '12 at 11:03
  • More about overwriting the hit testing method: http://smnh.me/hit-testing-in-ios/ – Tim Chen Nov 24 '14 at 01:22
5

Mike,

use the approach from my blog that Ben linked you to. Make the UIScrollView half the size of the surrounding view (i.e. 150px) and move it to the left instead of leaving it centered.

That should give you exactly the behaviour you wanted.

Cheers, Alex

Alex Repty
  • 1,060
  • 1
  • 9
  • 17
4

It can surely be done with the help of scrollview delegate methods & content-offset.

Below is the detailed code for the same.

int start;

int end;

int k=0;

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView1
{

    pageControlUsed = NO;

    start = scrollView.contentOffset.x;

}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView1 willDecelerate:(BOOL)decelerate
{

    end = scrollView.contentOffset.x;

}   


- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView1{

    int diff = end-start;

        if (diff>0)
        {

         k=k+150;
         [scrollView setContentOffset:CGPointMake(k, 0) animated:YES];

        }
       else {

         k=k-150;
        [scrollView setContentOffset:CGPointMake(k, 0) animated:YES];

          }
}
The iOSDev
  • 5,237
  • 7
  • 41
  • 78
Himanshu
  • 421
  • 3
  • 10
2

Simply override scrollViewWillEndDragging

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
    CGFloat pageWidth = 160;
    targetContentOffset->x = pageWidth * (int)(targetContentOffset->x / pageWidth);
}
Nico
  • 1,580
  • 14
  • 21
1
UIScrollView *album = [[UIScrollView alloc] init];
album.translatesAutoresizingMaskIntoConstraints = NO;
album.pagingEnabled = YES;
album.clipsToBounds = NO;
album.showsHorizontalScrollIndicator = NO;
album.contentInset = UIEdgeInsetsMake(0, -50, 0, -50);
[view addSubview:album];


[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-50-[_album(220)]" options:0 metrics:metrics views:views]];

[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_album(300)]" options:0 metrics:metrics views:views]];

this works fine on iOS 7.1~ 8.2

Pluuuuto
  • 11
  • 1