I had no trouble finding code elsewhere to use UIPageViewController’s however I found that there was little for paging through actual view controllers. On top of that, the examples that did exist had a lot of added on code instead of the barebones approach which I prefer.

While not a tutorial this is more of a dump of my barebones controller some added description. This code uses iOS 8 however it will likely work on iOS 7 as well.

Setup:

Screen Shot 2015-06-09 at 2.14.30 PM
The first step is to create other UIViewControllers on your storyboard that will be used to page through. You will need to provide them each with a unique Storyboard ID as well as a Restoration ID as we will reference the view controllers that are to be used by ID.

Screen Shot 2015-06-09 at 2.18.53 PM

Add your Page View Controller to your storyboard if you have not already done this. In my storyboard I segued over to this after a button was pressed.  There will be no segues or connections from this controller to the other view controllers you wish to page through as the rest is done through code. No storyboard or restoration ID is required for this controller.

Screen Shot 2015-06-09 at 2.35.04 PM

 

On the page view controller change the transition style to scroll and navigation to horizontal.

Code:

At this point, all that is left is code for the Page View Controller!

DashboardPageViewController.h

#import <UIKit/UIKit.h>

@interface DashboardPageViewController : UIPageViewController <UIPageViewControllerDataSource, UIPageViewControllerDelegate>

@end

DashboardPageViewController.m

#import "DashboardPageViewController.h"

@interface DashboardPageViewController ()

@end

@implementation DashboardPageViewController{
    NSArray *m_pages;   //Stores the names of the restoration ID's. This is the data-source so to speak.
}

- (void)viewDidLoad {
    [super viewDidLoad];

    self.dataSource = self;
    self.delegate = self;

    //Provide the restoration ID's here
    m_pages = @[@"DashboardViewController", @"DashboardViewController6Pack"];

    //Set up the initial VC
    UIViewController* curController = [self loadPageWithName:[m_pages objectAtIndex:0]];
    [self setViewControllers:@[curController] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil];
}

#pragma mark - UIPageViewControllerDatasource and UIPageViewControllerDelegate methods

//Returns the VC that should be shown going forward
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController{
    return [self loadPageWithName:m_pages[[self getIndexFromRestoreId:viewController.restorationIdentifier isNext:YES]]];
}

//Returns the VC that should be shown going back
-(UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController{
    return [self loadPageWithName:m_pages[[self getIndexFromRestoreId:viewController.restorationIdentifier isNext:NO]]];
}

-(NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController{
    return [m_pages count];
}

-(NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController{
    //Only called on init to tell controller which page to start on
    return 0;
}

//Here we take the restoration id, get the direction (this is called from UIPageViewControllerDatasource methods)
//and determine the index which is correct for the result based off our m_pages variable.
-(int)getIndexFromRestoreId:(NSString*)restoreId isNext:(BOOL)isNext{
    //Gets the current index from the pages array. This is the index of the page it is on before the swipe occurred.
    int nextIndex = (int)[m_pages indexOfObject:restoreId];

    //Now go left or right in the array based on what the UIPageController tells us
    if(isNext)
        nextIndex++;
    else
        nextIndex--;

    //If we went out of bounds on the array, just start over on the other side
    if(nextIndex < 0)
        nextIndex = (int)[m_pages count] - 1;
    if(nextIndex >= [m_pages count])
        nextIndex = 0;

    NSLog(@"Returning index %i", nextIndex);

    return nextIndex;
}

-(UIViewController*)loadPageWithName:(NSString*)pageName{
    //This method turns the current index being viewed into the related view conrtoller that will be shown.
    NSLog(@"Loading page %@", pageName);
    UIViewController *vc=[[self storyboard] instantiateViewControllerWithIdentifier:pageName];

    return vc;
}

@end

Be sure to update the m_pages with the names of your restoration ID’s to get this example to work. Also remember that you will need to assign your Page View Controller with this class. No other customization should be needed.

Questions? Comments? Let me know.

Comments 1

  • Hi Mike, I was searching for hours and found your code. Thank you it works great.

Leave a Reply

Your email address will not be published. Required fields are marked *