iOS Dev Notes

iOS Development From The Frontlines

How To: UIScrollView with Paging

with 88 comments

Creating a UIScrollView with paging is fairly straightforward — with a few caveats. In this post I’ll walk through a simple app that allows the user to scroll through multiple pages, adding a UIPageControl for further control.

Getting Started

To start, create a new XCode project. Choose “View-based Application” as this gives us a UIViewController sub-class and XIB for free.

Let’s add a UIScrollView to the view. First add an outlet for the scroll view in the view controller, and in Interface Builder drag in a UIScrollView and link it to the outlet. For now this scroll view can take up the full height and width of the parent view.

At this point our header file contains a single property:

@interface UIScrollView_PagingViewController : UIViewController {
    UIScrollView* scrollView;
}
 
@property (nonatomic, retain) IBOutlet UIScrollView* scrollView;
 
@end

The implementation is straightforward as well:

#import "UIScrollView_PagingViewController.h"
 
@implementation UIScrollView_PagingViewController
 
@synthesize scrollView;
 
- (void)viewDidLoad {
    [super viewDidLoad];
}
 
- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
 
    // Release any cached data, images, etc that aren't in use.
}
 
- (void)viewDidUnload {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
    self.scrollView = nil;
}
 
- (void)dealloc {
    [scrollView release];
    [super dealloc];
}
 
@end

Here’s what the XIB looks like:

Adding the scroll view

Now let’s add some content to the scroll view. Into viewDidLoad let’s add a few pages of solid colors, each one the size of the scroll view:

- (void)viewDidLoad {
    [super viewDidLoad];
 
    NSArray *colors = [NSArray arrayWithObjects:[UIColor redColor], [UIColor greenColor], [UIColor blueColor], nil];
    for (int i = 0; i < colors.count; i++) {
        CGRect frame;
        frame.origin.x = self.scrollView.frame.size.width * i;
        frame.origin.y = 0;
        frame.size = self.scrollView.frame.size;
 
        UIView *subview = [[UIView alloc] initWithFrame:frame];
        subview.backgroundColor = [colors objectAtIndex:i];
        [self.scrollView addSubview:subview];
        [subview release];
    }
 
    self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * colors.count, self.scrollView.frame.size.height);
}

For each color in our colors array, we’re creating a subview the height and width of the scroll view, located increasingly further to the right. Finally, we set the the scroll view’s content size (that’s the size of all the stuff inside the scroll view).

If you run the app at this point, you’ll see that although you can scroll between “pages”, when you let go the scroll view stays put. When we think of “paging”, that means the user is locked into concrete pages, and once they let go of the scroll view they should be locked into a specific page.

Enabling paging

Luckily, doing this is quite simple. UIScrollView has a property called “pagingEnabled” which does exactly what I described in the last paragraph. You can set this in code or in Interface Builder. Let’s set it in Interface Builder. At the same time, we can hide the scrollers as well. Generally you don’t see scrollers inside paged scroll views.

At this point, if you’re not interested in adding a page control, you’re done! However, we’ll continue with setting up a page control, which is common for a UIScrollView with paging.

Adding the UIPageControl

The UIPageControl view is generally used anywhere the user can visually choose between discrete pages or slides. Think of the home screen, Safari, Weather, and so on.

Let’s add a UIPageControl to the app. In Interface Builder, resize the scroll view to allow for some space below it for the page control. Next, drag in a UIPageControl from the library, centered below the scroll view. Resize the UIPageControl to take up the full width of the view. I’d also recommend setting the background color of the parent view to black, just so we can more clearly see the page control.

If you try running the app, everything looks right, but our page control isn’t updating as we scroll from page to page. Let’s do that next.

Hooking up the UIPageControl

Add an outlet to the view controller called “pageControl”. In Interface Builder, connect the UIPageControl to this outlet. Now we have access to the pageControl in the view controller.

If we want the page control to update as the user changes pages, we’ll need to know when the user scrolls. For that we can use the scroll view’s delegate, UIScrollViewDelegate. We can have our view controller be the delegate. So, add the UIScrollViewDelegate protocol to our view controller, and in Interface Builder, connect the scroll view’s “delegate” outlet to our view controller.

When all that’s done, the view controller’s header file should look like this:

@interface UIScrollView_PagingViewController : UIViewController  {
    UIScrollView* scrollView;
    UIPageControl* pageControl;
}
 
@property (nonatomic, retain) IBOutlet UIScrollView* scrollView;
@property (nonatomic, retain) IBOutlet UIPageControl* pageControl;
 
@end

And the XIB:

UIScrollViewDelegate gives a whole bunch of useful methods, but the one that helps us here is “scrollViewDidScroll:”. It let’s us know that the user has scrolled the content view inside the scroll view.

So when should we update the page control? If you play with one for a bit (say, the one on your iPhone’s home screen) you’ll see that the page actually changes once you’re halfway scrolled to the previous or next screen. So as the user scroll’s, we’ll need to keep an eye on how far they’ve scrolled to the right, and figure out the closest page.

Add the following method to the view controller:

- (void)scrollViewDidScroll:(UIScrollView *)sender {
    // Update the page when more than 50% of the previous/next page is visible
    CGFloat pageWidth = self.scrollView.frame.size.width;
    int page = floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
    self.pageControl.currentPage = page;
}

The page is computed by first starting with self.scrollView.contentOffset.x, which is how far the user has scrolled. Then subtracted from that is the half the width of a page (since the page number actually changes as the user scrolls by the midpoint of a slide). Dividing by the page width and rounding down gives the page count assuming the first page is 0. Since UIPageControl expects the first page to be 1, we add 1 to this count. Setting currentPage on the page control will automatically update the UIPageControl’s UI.

Try running the app again and as you scroll between pages you should see the page control respond just as you would expect.

Responding to the UIPageControl

However, we’re only half-way there. The page control updates as the user scroll’s between pages, but we also want to be able to switch between pages by tapping on the left or right side of the page control.

We can use the “value changed” event on UIPageControl to be told when the user changes the page using the control. Add an IBAction method called “changePage” the view controller’s header file:

- (IBAction)changePage;

In Interface builder, connect this up to the “value changed” action on the page control.

The implementation of this method is fairly straightforward:

- (IBAction)changePage {
    // update the scroll view to the appropriate page
    CGRect frame;
    frame.origin.x = self.scrollView.frame.size.width * self.pageControl.currentPage;
    frame.origin.y = 0;
    frame.size = self.scrollView.frame.size;
    [self.scrollView scrollRectToVisible:frame animated:YES];
}

You can pragmatically make a UIScrollView scroll by calling scrollRectToVisible:animated. You pass it a rectangle which you’d like to be made fully visible. In this case, that’s the new page to which we want to scroll. I’d recommend always setting animated to YES so that it’s clear to the user what’s happening.

If you try the app out it should work great…with one exception. You may notice the page control “flashing” when you use it to change pages. The page control will switch to the correct page, then switch back to the old page, and finally switch to the original, correct, page. Let’s fix that.

Fixing the flashing

What’s happening here is that when we tell the scroll view to scroll with scrollRectToVisible:animated:, the scrollViewDidScroll: method still gets called. So it will revert to the old page until we scroll past 50% of the old page, after which the page control will switch back.

So what we need to do is prevent the code in scrollRectToVisible:animated: from running if the page control was used to initiate the scroll. Add an BOOL attribute called pageControlBeingUsed to the view controller, and set it to NO in viewDidLoad.

We know we can turn it to YES when the user changes the page, so add “pageControlBeingUsed = YES;” to the end of the changePage method.

But when do we set it back to NO? There are two cases: either the user interrupts our page control driven scrolling by manually initiating a scroll, or the scroll finishes. Luckily we can use UIScrollViewDelegate to be notified of both these events:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    pageControlBeingUsed = NO;
}
 
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    pageControlBeingUsed = NO;
}

This should now fix our flashing problem, and provide us with a fully complete paging UIScrollView, with UIPageControl. I’ve made all the code in this tutorial available here. Feel free to use it as a starting point in your own projects.

I hope you found this tutorial useful! If you did, please consider signing up for my newsletter to be notified of new blog posts as well as receiving periodic tips, tricks and suggestions that I don’t post on my blog.

Update: In the comments, some people have asked about placing buttons inside the scroll view, and also about setting up the scroll view using Interface Builder. I’ve added some code that includes buttons here, and a version using Interface Builder here.


Looking to add push notifications to your iOS app? Check out PushLayer, a service from the authors of iOSDevNotes.

Bookmark and Share

Subscribe for updates

Fill out the form below to join my newsletter. I'll also send you a bonus copy of my ebook, "5 Steps To Becoming a Better iOS Developer".

Written by cwalcott

March 3rd, 2011 at 1:58 pm

88 Responses to 'How To: UIScrollView with Paging'

Subscribe to comments with RSS or TrackBack to 'How To: UIScrollView with Paging'.

  1. I have a doubt.

    I want to click in determinate page (and go to another pageviewcontroller), how i can do it?

    moosc

    8 Mar 11 at 6:57 am

  2. But if you want to improve the code, you can delete the colors and add a group of imageviews, that when you click it goes to another view controller ;)

    moosc

    8 Mar 11 at 7:27 am

  3. Hi! Thank you for your clear instructions. I wasn’t able to finish the project because xCode is telling me there’s a problem i.e. error ‘lt’ undeclared and another for the same line says Expected ‘)’ before ‘:’ token.

    This is the line within the code for viewDidLoad
    for (int i = 0; i < colors.count; i++) {

    I’d be most grateful if you have a solution.

    Diane Challenor

    11 Mar 11 at 3:39 pm

  4. That was some HTML that wasn’t properly escaped. I’ve updated the post. Thanks for the heads up.

    cwalcott

    11 Mar 11 at 3:42 pm

  5. You could use a UIGestureRecognizer to catch when someone taps on each of the views.

    cwalcott

    11 Mar 11 at 3:43 pm

  6. Hi, I’ve solved the problem when I realised &lt is the HTML equivalent of the less than symbol i.e. <

    Here's the code correction:
    for (int i = 0; i < colors.count; i++) {

    Let me know if the code is correct.

    Thanks,

    Diane Challenor

    11 Mar 11 at 4:08 pm

  7. Our comments crossed over. Thanks for your quick response.

    Diane Challenor

    11 Mar 11 at 4:09 pm

  8. Hi Costa,

    I’m just beginning to understand iOS development :-)

    In your code I see an if-construction in the scrollViewDidScroll method to check if pageControlBeingUsed, but it’s not mentioned on this page. Seems to me this is crucial to get rid of the pageControl flashy problems.

    Anyway, thanx a lot for this great tutorial.

    Ruud

    26 Mar 11 at 9:02 am

  9. Hi Ruud,

    Check out the “Fixing the flashing” section. pageControlBeingUsed is added as an attribute of the view controller.

    -Costa

    cwalcott

    28 Mar 11 at 3:56 pm

  10. Is it possible to use this as a base for a view like the “iAd Gallery” app from Apple ?

    OE

    18 Apr 11 at 2:42 pm

  11. Definitely!

    cwalcott

    20 Apr 11 at 3:58 pm

  12. I have a view based app that have some buttons in the main viewcontroller. Each button gets another view and in one of those i have integrated your code in this tutorial.

    I can switch between the colors in the scrollview and when i klick the three dots in the page control, the scrollview change page too.

    My problem is that when i scroll the scrollview, the dots does not change. I have tried to fix this for some hours now but i cant get it working.
    It seems to me that;

    “- (void)scrollViewDidScroll:(UIScrollView *)scrollView”

    does not execute. I have a row at first line that should print to the NSLog but i dont get that message.

    I know that this tutorial does not count in projects with the scroll and paging system as subviews but i thought that it would have the same principle.

    If you have an spontaneous answer to my question i would be very grateful.

    thanks in advance.

    //Kristoffer

    Kristoffer

    23 May 11 at 8:51 am

  13. Okey. I know why it doesnt work. You cant do it the same way in XCode 4. It would be great if you would like to create an new tutorial, how to do this in XCode 4. There is not many good tutorials out there what i have seen. I really liked yours. To bad its not for XCode 4 as i hoped for. Thanks alot for this tutorial anyway. It was realy great and you write it very understandable. Continue your good work! :)

    Thx! //Kristoffer

    Kristoffer

    23 May 11 at 9:22 am

  14. Hi Kristoffer,

    Do you think you could share some of your code that didn’t work? I believe everything in the tutorial should work in Xcode 5 as well.

    -Costa

    cwalcott

    25 May 11 at 3:02 pm

  15. Thanks for your fast answer :) The problem is that i dont know what code it is that doesnt work. I dont even think its the code. The
    “- (void)scrollViewDidScroll:(UIScrollView *)scrollView”-code does not execute and it seems to me that its because the connections in the nib file´s not right.

    Maybe im wrong but if so, i dont know what code to show you.

    Is´nt it right that if the connection in the IB is not right, the control does not have the methods or attributes to shown to the code in my “.m” file?

    Kristoffer

    27 May 11 at 6:04 am

  16. Awesome tutorial. I was looking for something like this all day. I am pulling in a json string to this page and am trying to get a label to update to each time you swipe. I can get the first one to display, but after that there is no label. I imagine it has something to do with the subview you created for the background color. I am not even sure this will work, but I was hoping you could help me out.

    here is my code:

    self.index = 0;

    pageControlBeingUsed = NO;

    for (int i = 0; i < self.tipsArray.count; i++) {
    CGRect frame;
    frame.origin.x = self.scrollView.frame.size.width * i;
    frame.origin.y = 0;
    frame.size = self.scrollView.frame.size;

    UIView *subview = [[UIView alloc] initWithFrame:frame];

    NSDictionary *itemData = [self.tipsArray objectAtIndex: self.index];
    NSString *tip = [itemData objectForKey: @"tip"];

    self.tipLabel.text = tip;

    //subview.backgroundColor = [colors objectAtIndex:i];
    [self.scrollView addSubview:subview];
    [subview release];

    self.index = self.index++;
    }

    self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * self.tipsArray.count, self.scrollView.frame.size.height);

    self.pageControl.currentPage = 0;
    self.pageControl.numberOfPages = self.tipsArray.count;
    }

    Yurkie

    3 Jun 11 at 12:18 am

  17. Hi Yurkie,

    I think the problem is that you only have one label, which is on the first page. Think about the scroll view as being one really wide view, and as you scroll from page to page, you look at smaller parts of that view. So if you’d like the label to visible on every page, you probably want to create a separate label for each page. Or, you could move the label into the visible portion of the scroll view every time a page changes (perhaps in the changePage method).

    Hope that helps,
    -Costa

    cwalcott

    6 Jun 11 at 11:47 am

  18. Thanks. That helped

    Yurkie

    8 Jun 11 at 9:21 pm

  19. How would you integrate storyboard into creating such an app? With Xcode 4.2 and iOS5 SDK (+ potentially storyboarding) I’m just about to build an app with scrollviews and and page control…how would you do it with storyboard?

    Emmanuel Henri

    25 Jun 11 at 5:44 pm

  20. If anyone cannot get the pagecontrol to respond add the delegate in the .h file and add scrollView.delegate = self; in the viewDidLoad on the .m file. Used Xcode 4.

    Mmmmonster

    11 Jul 11 at 6:41 am

  21. Hi,
    good tutorial i have been working on my first app and i need to implement a page control feature with some images 5-6. i have been trying to use the “page control” Apple sample code but because i need to do it in landscape orientation the way in they wrote the sample code and what i have to do proved incopatible. your tut however, is very streamlined and clear. my question is to use the images do i only need to modify the array? some help would be really appreciated.
    thanks

    Carlo

    18 Jul 11 at 12:11 pm

  22. Hi Carlo,

    Yes, to use images, you could have an array of UIImage objects, and when adding subviews, you could use UIImageView instead of UIView.

    -Costa

    cwalcott

    25 Jul 11 at 12:09 pm

  23. Thanks for the good stuff here. I am having a tough time using this with images… I think the answer is in viewDidLoad but I’m not sure how to execute… I have tried;

    [super viewDidLoad];

    NSArray *images = [NSArray arrayWithObjects:[UIImage imageNamed:@"sb_1.jpg"], [UIImage imageNamed:@"sb_2.jpg"], [UIImage imageNamed:@"sb_3.jpg"], nil];
    for (int i = 0; i < images.count; i++) {
    CGRect frame;
    frame.origin.x = self.scrollView.frame.size.width * i;
    frame.origin.y = 0;
    frame.size = self.scrollView.frame.size;

    UIView *subview = [[UIImageView alloc] initWithFrame:frame];
    subview.UIImageView = [images objectAtIndex:i];
    [self.scrollView addSubview:subview];
    [subview release];

    Can you take a look and tell me if I am going in the right direction?

    Thanks!

    RGNelson

    29 Jul 11 at 9:24 pm

  24. I got this irking with this;

    NSArray *images = [NSArray arrayWithObjects:[UIImage imageNamed:@"sb_1.jpg"], [UIImage imageNamed:@"sb_2.jpg"], [UIImage imageNamed:@"sb_3.jpg"], nil];
    for (int i = 0; i < images.count; i++) {
    CGRect frame;
    frame.origin.x = self.scrollView.frame.size.width * i;
    frame.origin.y = 0;
    frame.size = self.scrollView.frame.size;

    UIImageView *subview = [[UIImageView alloc] initWithFrame:frame];
    subview.image = [images objectAtIndex:i];
    [self.scrollView addSubview:subview];
    [subview release];

    RGNelson

    30 Jul 11 at 1:28 pm

  25. [...] Para crear el panel de control tipo “dock”, como el de appsender, o el de la aplicación de facebook, o la de grooveshark, dropbox, etc. es decir la primera pantalla, podéis seguir este magnífico tutorial: How to connect UIScrollView with UIPageControl. [...]

  26. i have to display 12 icon in the 1st page and if it is more than 12 then that comes into next page and so on. here i m displaying icons into cell by using UITableView.
    can u help me… please

    lucky

    18 Aug 11 at 1:09 am

  27. How would I be able to make this into like an app so people can save the picture to their ipod, then use it for a background?

    Great tutorial btw, it helped me get started on a little project of my own.

    Jack

    19 Aug 11 at 4:29 pm

  28. Hi. I have done a similar project using the page control scrolling by colors. can i know how to change it from scrolling colors to scrolling to a new xib file that i have?
    This is my code:

    UIScrollView *myScrollView;
    UIPageControl *myPageControl;

    @implementation RoastedPorkRice

    - (void)loadScrollViewWithPage:(UIView *)page
    {
    int pageCount = [[myScrollView subviews] count];

    CGRect bounds = myScrollView.bounds;
    bounds.origin.x = bounds.size.width * pageCount;
    bounds.origin.y = 0;
    page.frame = bounds;
    [myScrollView addSubview:page];
    }

    - (void)createPages
    {
    CGRect pageRect = myScrollView.frame;

    //create pages
    UIView *page1 = [[UIView alloc] initWithFrame:pageRect];
    page1.backgroundColor = [UIColor blueColor];
    UIView *page2 = [[UIView alloc] initWithFrame:pageRect];
    page2.backgroundColor = [UIColor redColor];
    UIView *page3 = [[UIView alloc] initWithFrame:pageRect];
    page3.backgroundColor = [UIColor greenColor];

    //add to scrollview
    [self loadScrollViewWithPage:page1];
    [self loadScrollViewWithPage:page2];
    [self loadScrollViewWithPage:page3];

    //cleanup
    [page1 release];
    [page2 release];
    [page3 release];
    }

    Elton

    26 Aug 11 at 3:58 am

  29. And also, my xib files are just actually a very big button that is an image

    Elton

    26 Aug 11 at 4:01 am

  30. In that case, you might not actually need to use xib files: perhaps you could create the buttons programmatically and add them to the views. Otherwise, you should be able to get access to the view inside the xib, and simply add them to the scroll view as child views.

    cwalcott

    31 Aug 11 at 5:07 pm

  31. Hey cwalcott, awesome tutorial man! Thanks a lot!
    I was wondering if its possible to have a scroll view on each view (each color) that allows the user to scroll up and down. And I have no idea how to add that. I also wanted to add a tab controller and a navigation controller at the top, but I guess thats pretty easy, right?

    So if you can help me out to add that vertical scrolling, then that would be awesome.

    Richard

    2 Sep 11 at 2:05 pm

  32. Hi thanks for this, this was just what I needed for my app to show some of the features that are in it.

    I got it all to work perfectly, but I was wondering how to put like text and images on each separate page (and images).

    That is the part that confuses me. If you can help then I can be done :)

    Thanks again!
    //Brandon

    Brandon

    5 Sep 11 at 1:15 am

  33. But however i would need to use xib files as that image button leads to another file. It would be like a food ap with big a picture and when i click it, it loads onto a review page but when i slide the picture, it slides onto another big picture.

    Elton

    5 Sep 11 at 4:57 am

  34. pardon me if i sound noob cause i’ve just started learning xcode.

    Elton

    5 Sep 11 at 4:59 am

  35. Hi Richard,
    I would probably just add individual UIScrollView subviews of the sizes of each page.

    cwalcott

    7 Sep 11 at 12:19 pm

  36. Thanks cwalcott! It worked.
    Just I have a even bigger problem now, I think. So I have a View, and in that view I have a Scroll View and a Page Control. Everything is working fine. I can swipe between pages, and I can scroll down and up the page to reveal more of the image thats on top of scroll view. However, when I scroll down to the bottom of the page and then swipe horizontally to the next page, the image thats on the next page is also scrolled down to the bottom. I perfectly understand that, because I’m moving everything down when I scroll down one image.

    So I was wondering, is the following possible, with UIScrollView and UIPageControl:
    I scroll down the image on a page, and when I swipe the UIPageControl to get another page, the image on that page is automatically scrolled up to the top. I’m kind of looking for something similar to the CNN app.

    Does the scrollsToTop command do anything like that?

    Richard

    14 Sep 11 at 3:04 pm

  37. Hello, it’s the wonderfull tutorial, i ahve only one question:

    How to change this portion of code to implement o use only my XIB / NIB pages?

    THX to mutch.

    - (void)viewDidLoad {
    [super viewDidLoad];

    pageControlBeingUsed = NO;

    NSArray *colors = [NSArray arrayWithObjects:[UIView:@"pagina1" bundle:nil], [UIColor greenColor], [UIColor blueColor], [UIColor yellowColor], nil];
    for (int i = 0; i < colors.count; i++) {
    CGRect frame;
    frame.origin.x = self.scrollView.frame.size.width * i;
    frame.origin.y = 0;
    frame.size = self.scrollView.frame.size;

    UIView *subview = [[UIView alloc] initWithFrame:frame];
    subview.backgroundColor = [colors objectAtIndex:i];
    [self.scrollView addSubview:subview];
    [subview release];
    }

    KING MILANO

    26 Sep 11 at 2:56 pm

  38. Hi Cwalcott,

    I am having one problem which I hope you can help me address. The scrolling works fine and paging is great too thanks.

    My problem is that on each page I put a UIButton which when pressed caries out a certain request. My problem is that I can’t click the UIButtons when they are in the UIScrollView. Do you know why?

    Its only in your UIScrollView with Paging Xcode project that this happens. When I made a simple Xcode project on my Mac and added a UIScrollView on its own with some UIButtons the user can press the buttons….. This seems weird.

    What am I doing wrong?

    Please help.

    Dan

    Dan

    11 Oct 11 at 5:19 pm

  39. Hi Dan,

    I just updated the project to include buttons on each page. I put it on a separate branch of the project: https://github.com/cwalcott/UIScrollView-Paging/tree/buttons.

    Also feel free to share the code that’s giving you trouble, or you can email me directly (cwalcott@iosdevnotes.com).

    cwalcott

    12 Oct 11 at 10:59 am

  40. Hi Cwalcott,
    I have a simular problem that when I add buttons on the scrollview in Interface Builder it doesnt show them when I run it in the simulator. I have a lot of buttons with images and I would like to use the IB because then it is very easy to add an image etc.
    What am I doing wrong?
    Bas

    Bas

    25 Oct 11 at 6:55 am

  41. Hi Cwalcott,

    Thanks for your reply and project update. It was very helpful. However I now still have one problem. I was expecting you to add the UIButton manually but instead you added the UIButton programatically (which seems perfectly fine) but then only problem I have now is that I can’t seem to be able to change the image of the UIButton. You see I don’t want any text on my UIButton, I just want to add a picture to it.

    How can I do this?

    Also is there a way I could manually (using interface builder) add the UIButton to the ScrollView?? Because I tried this but when I try to press the UIButton, I can’t… Why?

    Please help :D

    Thanks,

    Dan

    Dan

    25 Oct 11 at 12:06 pm

  42. To do it programmatically, you could just remove the line that sets the title, and can set the currentImage property.

    As for using Interface Builder, I just posted a new branch that sets up the scrollview in IB, and uses images for the buttons: https://github.com/cwalcott/UIScrollView-Paging/tree/buttons-ib. The way I did it was to drag the UIScrollView outside of its containing view, then resize it to its full size (in this case 960×424). Then after setting up all the buttons, I resized it back down to 320×424 and put it back inside the view.

    I hope this helps.

    cwalcott

    26 Oct 11 at 11:22 am

  43. Checkout my response to Dan. Perhaps this code will help: https://github.com/cwalcott/UIScrollView-Paging/tree/buttons-ib.

    cwalcott

    26 Oct 11 at 11:23 am

  44. Hi Cwalcott,

    I can’t possibly thank you enough :D

    You replied to my questions so quickly, you updated your projected for me and all other who requested updates and you do it all for free. Thank you so much!!!!!!

    PLEASE PLEASE keep up the awesome work.

    All my problems with this project have now been resolved. I am working on a app which implements this and I would like to show you the app once its on the app store. I will post a link here. Just to show my appreciation, for you to see how I implemented your project into my app.

    Thank you once again.

    Regards,

    Dan – A very happy developer :D

    Dan

    26 Oct 11 at 1:57 pm

  45. You’re welcome! I’m glad I was able to help.

    cwalcott

    26 Oct 11 at 3:10 pm

  46. Brilliant tutorial, thanks. I’m putting together an iPad app (landscape) to hold some slides (just simple image files) and this looks the perfect way to do it. The problem I’m having is that I want them separated into “chapters”, so that I can swipe down through the pages of one chapter to the end, then swipe across to the top of he next chapter (where I then continue down to the end of that chapter), etc.

    I’m a little unsure of how to achieve this two-way navigation, though. Could it perhaps be done with the new storyboarding feature in Xcode 4.2? I haven’t looked at that yet – it’s taken me long enough to get my head around how XIB files work!

    Any pointers would be gratefully received. :o)

    Thanks,

    James

    James

    30 Oct 11 at 8:17 am

  47. James, off the top of my head I would say perhaps you could have the chapter scroll views nested inside of a larger container scroll view. You also might want to check out gesture recognizers (UIGestureRecognizer).

    cwalcott

    2 Nov 11 at 3:25 pm

  48. Thanks for the great tutorial! I put a table view on each page and it works like a charm.

    Dimitar Chakarov

    10 Nov 11 at 12:55 pm

  49. Will this work for a UIWebView’s scrollview? Starting in iOS 5.0, we can access a web view’s scrollview, so I’m wondering if we can use this to create something like facebook’s pictures where you can slide from one picture to the next.

    Yash

    11 Nov 11 at 12:34 am

  50. Hmm interesting idea. I suppose you could do this within a UIWebView.

    cwalcott

    11 Nov 11 at 10:58 am

  51. Hi Costa

    Awesome tutorial! How could I amend the paging with buttons tutorial so that there is a gap between each button displayed like you have with the tabs view in iPhone Safari? What I mean is that the edges of the buttons to the side of the central button can be seen. Hope I explained myself properly :o)

    Spidey2010

    20 Nov 11 at 7:26 pm

  52. hi , Thank you so much I just followed this . This is works great .

    suresh

    29 Nov 11 at 3:04 am

  53. Hey Costa, I am trying to create an app that uses horizontal scroll paging. I have created one nib that has a UIScrollView and I have extended the scroll view so that it is three times the width of the screen, so basically three pages wide. I can almost get it to work but when you scroll or page it skips straight past page 2 and goes to page three. Any ideas on what I can do?

    Thanks,
    Jason

    Jason

    30 Nov 11 at 6:23 am

  54. Thank you for the tutorial. I am trying to display a group of text labels and two images in the equivalent of each page view.

    Can I do that in a ScrollView?

    If not, do you have any ideas on how to do it that you can point me at?

    Thank,

    padapa

    padapa

    5 Dec 11 at 5:37 pm

  55. Spidey2010, I think you could do this just by changing the size of each page view.

    cwalcott

    8 Dec 11 at 11:29 am

  56. Hi Jason, I’d probably have to see the code to get a better idea. Feel free to email me directly at cwalcott@iosdevnotes.com.

    cwalcott

    8 Dec 11 at 11:36 am

  57. Hi padapa, that should be doable. You can add whatever subviews you’d like into each page’s view. If the content of each page is different, you may want to create them one by one instead of in the for loop.

    cwalcott

    8 Dec 11 at 11:41 am

  58. Hey guys! I need to insert a web view into each of these pages. Any ideas on how that would be done?

    Steven

    11 Jan 12 at 5:26 pm

  59. Hello Cwalcott,
    I’m working on app and I need to insert a web view into each of these pages. I don’t want the user to interact with the views, they should display the top left of a web page. If you can give me any help on how I would do this. A quick response would be appreciated. Thanks

    YummySnacks

    16 Jan 12 at 8:01 pm

  60. There is an easier way to fix the “flashing” of the page indicator.

    set “defersCurrentPageDisplay” of the pageControl to YES.
    Now the UIPageControl doesn’t update the white dot automatically.

    That’s why you have to add “[self.pageControl updateCurrentPageDisplay]; to the end of “- (void)scrollViewDidScroll:(UIScrollView *)sender”. That will update the dot.

    Et voila. No need to add an instance variable bool.

    Matthias

    24 Jan 12 at 8:11 am

  61. Good tutorial

    code (including comments) very similar to Apple’s example

    http://developer.apple.com/library/ios/#samplecode/PageControl/Introduction/Intro.html

    Paul

    24 Jan 12 at 3:47 pm

  62. Hi,
    I’ve included this scroll view in a tabbar application (template for xcode) and the uicontrol scrollViewDidScroll method doesn’t trigger.
    Any idea ?

    Geoffrey Kretz

    25 Jan 12 at 4:22 pm

  63. Geoffrey this is just an idea but sometimes I’ve found when you transplant a scrollview into a view hierarchy two things can happen:
    #1 it can end up ‘below’ the view so touches are not registered
    #2 sometimes the user interaction is disabled. Either re enable it in the Xib or type in ViewDidLoad:
    scrollView.userInteractionEnabled = YES;

    Just my 2 cents, the author might have more insightful answers

    Dan M

    1 Feb 12 at 10:54 am

  64. Thanks Dan, but this doesn’t work.

    Geoffrey Kretz

    15 Feb 12 at 5:30 pm

  65. I got it, in the viewwillappear method of my scrollviewcontrolle, i missed :

    scrollView.delegate = self;

    Geoffrey Kretz

    15 Feb 12 at 5:57 pm

  66. Very awesome; thank you!

    Joshua Kaden

    16 Feb 12 at 1:29 pm

  67. Thanks for this tutorial, cwalcott. I have dealing with part of this tutorial to have a matrix of predefined ViewControllers attached to my ScrollView, and this stuff was the basis to implement it.

    voyager

    19 Feb 12 at 2:13 pm

  68. Thank you bery much CWallcot, you really have done something amazing:) I have a quetion; I used your sample code in my app and instead of colors i have some views. In my ap, i have an array of buttons which i want to add as sub views to this scrollview. If the count of my array is greater then 10 i want to add the buttons to second view. But i allways see a blank scrollview page(below is my code:)

    or (int i = 0; i < colors.count; i++) {
    CGRect frame;
    frame.origin.x = self.scrollView.frame.size.width * i;
    frame.origin.y = 0;
    frame.size = self.scrollView.frame.size;

    UIView *subview = [[UIView alloc] initWithFrame:frame];
    subview.backgroundColor = [colors objectAtIndex:i];
    [self.scrollView addSubview:subview];

    if(i==3){
    UIButton *button = [UIButton buttonWithType: UIButtonTypeRoundedRect];
    [button setTitle:@"Title 3" forState:UIControlStateNormal];
    button.frame = CGRectMake(40.0f, 50.0f, 450.0f, 70.0f);
    [scrollView addSubview:button];
    }

    [subview release];
    }
    i want, for example this button go to the 4. view in the array but nothing happens. Can you please help?

    ilhan

    20 Feb 12 at 11:36 am

  69. I’ve been playing about with this and I’ve been looking at various examples of getting a paging and scroll view to work – for me this was the example that really helped get my head round how it works – thanks for taking the time to write this simple stuff up in a way that helps us noobs get the hang of it!

    Pete McPhearson

    7 Mar 12 at 5:08 am

  70. I have been working very hard on uiscrollview to calculate page number with scrollViewDidScroll method with offset values. And I saw – (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
    method on your post. This way is very easy to solve it. Thank you very much…

    Ozgun

    23 Mar 12 at 9:00 am

  71. Slight update – add the UIScrollViewDelegate in the header to get access to the scroll methods.

    @interface UIScrollView_PagingViewController : UIViewController
    {
    UIScrollView* scrollView;
    UIPageControl* pageControl;
    }

    @property (n ….

    marbleblue

    27 Apr 12 at 10:10 am

  72. Your comment is awaiting moderation.

    Slight update – add the UIScrollViewDelegate in the header to get access to the scroll methods.

    @interface UIScrollView_PagingViewController : UIViewController <>
    {
    UIScrollView* scrollView;
    UIPageControl* pageControl;
    }

    @property (n ….

    marbleblue

    27 Apr 12 at 10:11 am

  73. This tutorial may be good, but it needs updating. I’ll bet most people are using the new Storyboard feature.

    Montana Burr

    2 May 12 at 2:33 pm

  74. Thanks a lot! this was so helpful!

    Federico

    3 May 12 at 8:51 pm

  75. amazing, this was a lot of help!!

    Thanks a lot.

    Keynes

    18 May 12 at 11:50 pm

  76. I don’t think you meant to say “So what we need to do is prevent the code in scrollRectToVisible:animated: from running if the page control was used to initiate the scroll.”

    Wouldn’t you want the view did scroll code to not run if the pagecontrol is being used? Like I have below. This worked for me and it also makes sense to me.

    if (!self.pageControlBeingUsed)
    {
    CGFloat pageWidth = self.resultsScrollView.frame.size.width;
    int page = floor((self.resultsScrollView.contentOffset.x – pageWidth / 2) / pageWidth) + 1;
    self.resultsPageControl.currentPage = page;
    }

    Tyler

    2 Jun 12 at 2:43 pm

  77. Hi – thanks for the tutorial. This is exactly what I was looking for. I’m in xCode4.3.2 and have been working to get this example to work. I got up to the half way point where the Page Controller is added in the interface builder. My problem is that it seems the (void)scrollViewDidScroll:(UIScrollView *)sender function never seems to fire when I scroll. I added a NSLog to fire when it is active, but it never prints in my console… Do you have any idea why this might be? My code for that function is noted below:
    - (void)scrollViewDidScroll:(UIScrollView *)sender {
    NSLog(@”x: test”);

    // Switch the indicator when more than 50% of the previous/next page is visible
    CGFloat pageWidth = self.scrollView.frame.size.width;
    int page = floor((self.scrollView.contentOffset.x – pageWidth / 2) / pageWidth) + 1;
    self.pageControl.currentPage = page;
    }

    Any help would be greatly appreciated.
    Robbie

    Robbie

    9 Jun 12 at 1:07 am

  78. Could you please do a work through of accessing a video from camera roll and then having an image of video in a thumbnail and then playing video full screen by clicking on thumbnail?

    thank you

    Toby

    13 Jun 12 at 9:46 pm

  79. great tutorial!

    irem

    19 Jun 12 at 7:06 am

  80. Thank you. Very easy/nice/thorough

    Thomas

    28 Jul 12 at 11:59 am

  81. Thank you sooo much for this tutorial! I tried a few but this is the first one which worked in a TabBarApp! Great tutorial! I signed up for your newsletter! Your awesome!

    SirNoob

    29 Aug 12 at 6:08 am

  82. Hi cwalcott,

    Nice Tutorial! I have a question though.. I plan on creating a PDF annotator app with scroll and zoom (and change page of course). Is it recommended to do paging for this type of app? As in using paging to switch from 1 page of the pdf to the next?

    kim

    30 Aug 12 at 10:53 am

  83. [...] I followed the tutorial about how to create a scrollView Page Control: http://www.iosdevnotes.com/2011/03/uiscrollview-paging/ [...]

  84. Great tutorial with very simplistic and minimal coding to illustrate the core of these features. Can you update it to mention the user must disable the view’s “Auto Layout”.

    At least as of Xcode 4.5, the default for the view is to enable “Auto Layout”, which breaks this tutorial if not unchecked.

    Thanks!

    Nathan

    3 Oct 12 at 9:12 pm

  85. thanks!

    Adan

    10 Oct 12 at 7:17 pm

  86. [...] I have implemented a paging UIScrollView following this excellent tutorial: http://www.iosdevnotes.com/2011/03/uiscrollview-paging/ [...]

  87. Hello,
    is it possible to have the same example running with rotation enabled?

    Cris

    14 Dec 12 at 7:04 pm

  88. - (void)viewDidLoad {
    [super viewDidLoad];

    // NSArray *colors = [NSArray arrayWithObjects:[UIColor redColor], [UIColor greenColor], [UIColor blueColor], nil];

    NSArray *image = [NSArray arrayWithObjects:[UIImage imageNamed:@"TeamWizard.png"],[UIImage imageNamed:@"MatchWizard.png"],[UIImage imageNamed:@"ProfileWizard.png"],[UIImage imageNamed:@"CommsWizard.png"],nil];

    for (int i = 0; i < image.count; i++) {
    CGRect frame;
    frame.origin.x = self.scrollView.frame.size.width * i;
    frame.origin.y = 0;
    frame.size = self.scrollView.frame.size;

    UIImageView *subview = [[UIImageView alloc] initWithFrame:frame];
    subview.backgroundColor = [image objectAtIndex:i]; <<< Thread 1
    [self.scrollView addSubview:subview];
    //[subview release];
    }

    I am a newbie in xcode, i really dont understand what is the error, please help me cwalcot.

    Jenny

    28 Dec 12 at 3:27 am

Leave a Reply