Paging With Collection Views (Part 2)

In last week’s post, I showed how a collection view with paging enabled and cells sized to fill the collection view’s bounds makes for an easy implementation of a paged user interface. In this week’s post we’ll complete the example by adding a page control as seen on apps like the standard iOS Weather app.

Creating the Page Control

We’ll need to refer to the page control throughout the view controller, so add a property for it to the interface section:

CollectionViewController.h

@interface CollectionViewController : UIViewController <uicollectionviewdelegate, uicollectionviewdatasource,="" uicollectionviewdelegateflowlayout="">

@property (strong, nonatomic) UICollectionView *collectionView;
@property (strong, nonatomic) UIPageControl *pageControl;
@end

At the end of the loadView method, add a new section of code to create the page control with a height of 60 points:

CollectionViewController.m

    CGFloat w = self.view.frame.size.width;
    CGFloat h = self.view.frame.size.height;

    // Set up the page control
    CGRect frame = CGRectMake(0, h - 60, w, 60);
    self.pageControl = [[UIPageControl alloc]
        initWithFrame:frame
    ];

    // Add a target that will be invoked when the page control is
    // changed by tapping on it
    [self.pageControl
        addTarget:self
        action:@selector(pageControlChanged:)
        forControlEvents:UIControlEventValueChanged
    ];

    // Set the number of pages to the number of pages in the paged interface
    // and let the height flex so that it sits nicely in its frame
    self.pageControl.numberOfPages = PAGES;
    self.pageControl.autoresizingMask = UIViewAutoresizingFlexibleHeight;
    [self.view addSubview:self.pageControl];

When the page control is tapped, we need to scroll the collection view by an appropriate amount. This is easily calculated using the width of the collection view and the current page:

CollectionViewController.m

- (void)pageControlChanged:(id)sender
{
    UIPageControl *pageControl = sender;
    CGFloat pageWidth = self.collectionView.frame.size.width;
    CGPoint scrollTo = CGPointMake(pageWidth * pageControl.currentPage, 0);
    [self.collectionView setContentOffset:scrollTo animated:YES];
}

We also need to update the page control when the page is changed by swiping. To do that, we implement the UIScrollViewDelegate protocol in the view controller:

CollectionViewController.h

@interface CollectionViewController : UIViewController <uicollectionviewdelegate, uicollectionviewdatasource,="" uicollectionviewdelegateflowlayout,="" uiscrollviewdelegate="">

@property (strong, nonatomic) UICollectionView *collectionView;
@property (strong, nonatomic) UIPageControl *pageControl;
@end

The method from the delegate protocol we are interested in is the method that is called by the scroll view (a collection view is a subclass of UIScrollView) when it stops scrolling. Again, we make a simple calculation to set the current page from the scroll position within the scroll view:

CollectionViewController.m

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    CGFloat pageWidth = self.collectionView.frame.size.width;
    self.pageControl.currentPage = self.collectionView.contentOffset.x / pageWidth;
}

Run the application and you should find that a page control appears at the bottom of the screen which updates as you swipe between pages and can be used to move between pages by tapping. One refinement you could add to this would be to subtract the the height of the page control from the collection view’s height so that the page control appears outside it.

So by adding a few more lines of code to last week’s example we have produced a nice little paged interface using collection views. Collection views are really flexible components and a great addition to iOS 6!

PS – PS – Have a look at our brand new course – Introduction to Swift Programming for Mac/iPhone/iPad, available in-class or online.

Richard Senior

Type to search blog.learningtree.com

Do you mean "" ?

Sorry, no results were found for your query.

Please check your spelling and try your search again.