2
votes

I am trying to create an app with horizontal scrolling, so that one would be able to scroll horizontally through a series of images. I watched the WWDC Session 104 video on this, and while they made an interesting app, they flew through the basics of it very quickly.

I understand using the UIScrollView, and that I have to enable paging. After that they say that I should add more views as subviews of the scrollview, but I am not clear on how to do that. I am also not clear on how I add my images to those views.

As you can probably tell I am pretty new at this so any help would be appreciated.

3

3 Answers

12
votes

You want to look into UIImageView. It's a view specifically for holding images.

When you add your images, you want to set their rects (probably using initWithFrame: for each UIImageView) so that:

  • the first image is at 0,0
  • the second image is at 320,0
  • third is at 640,0 (etc)

I.e. each image is 320 pixels right of the previous.

The final step is to set the contentSize for your UIScrollView -- this is a CGSize which describes the total size of the scroll view.

If you have 3 images, you would then set it to (320*3) * 480 using e.g.

myScrollView.contentSize = CGSizeMake(320*3, 480);

A lot of people, when they initialize the scroll view, have a for loop or similar which steps through the images they want to display. These for loops tend to look something like this:

CGFloat scrollWidth = 0.f;
for (UIImage *someImage in someNSArrayWithImages) {
    UIImageView *theView = [[UIImageView alloc] initWithFrame:
        CGRectMake(scrollWidth, 0, 320.f, 480.f)];
    theView.image = someImage;
    [myScrollView addSubview:theView];
    [theView release];
    scrollWidth += 320.f;
}
myScrollView.contentSize = CGSizeMake(scrollWidth, 480.f);

This way you'll get things lined up and you'll get the content size for you at the same time.

If you want to make it so that the scroll view "intelligently" scrolls to each image and stops when people slide left/right, you can do myScrollView.pagingEnabled = YES.

Hope that helps get you going.

1
votes

Assuming you have "infinite" images, putting them all there at or before launch time in a huge UIScrollView will not be an option. (there is a limit to the size of a UIView)

The way I solved it: Make a UIScrollView covering the whole screen. It's content should be a UIView of 3*320 width and 480 height, extending 320px left and 320px right.

Put 3 UIImageView's in it, left, middle and right. Set paging=YES, so the uiscrollview clips to the 3 "pages" you've created.

Make sure your class is the delegate of the uiscrollview, and listen for

-(void)scrollViewDidEndDragging:(UIScrollView*)sv willDecelerate:(BOOL)notFinished
-(void)scrollViewDidEndDecelerating:(UIScrollView*)sv
-(void)scrollViewDidEndScrollingAnimation:(UIScrollView*)sv

and make the appropriate transitions on hitting paging boundaries; shift images and set ContentOffset so you're looking at the center image again.

I suggest you make this first, and only then read on...

Then you will hit on a bug, documented here UIScrollView - (bounces = NO) seems to override (pagingEnabled = YES) and here http://www.iphonedevsdk.com/forum/iphone-sdk-development/935-paging-uiscrollview.html, which makes that you cannot disable bouncing and have paging enabled at the same time. So enable bouncing, and subclass UIScrollView, overruling setContentOffset in there to prevent bouncing. (having bouncing really enabled will make for a rather unusual user experience)

1
votes

Have a look at Apple's PageControl sample code. It's fairly short and easy to follow so you'll get the gist of setting up a project where multiple view controllers are loaded as you swipe horizontally.

Once you have this setup then it's the view controller's responsibility to load its own content (in your case, an image). You should make sure you understand how to load images first (using threads, etc) before you tackle paging, etc.

Think of it as two independent tasks. The view control is responsible for loading and displaying an image. The scroll view with paging just tells the appropriate view controller when to load itself (it doesn't care what the view controller does once its loaded)

Good luck!