Switching between view controllers that are loaded in the background
I recently created a similar layout for a project I'm working on using Apple's PageControl example as a base.

I used a UICollectionView for the top nav section and a UIScrollView for paging through view controllers. The main view controller is setup as below.



In the viewDidLoad method for the I set up the content size for the scrollView and set paging to YES.

[self.containerScrollView setContentSize:CGSizeMake(CGRectGetWidth(self.containerScrollView.frame)*self.numberOfPages, 
CGRectGetHeight(self.containerScrollView.frame))];
[self.containerScrollView setPagingEnabled:YES];
[self.containerScrollView setShowsHorizontalScrollIndicator:NO];
[self.containerScrollView setShowsVerticalScrollIndicator:NO];
[self.containerScrollView setScrollsToTop:NO];
[self.containerScrollView setDelegate:self];


(Note: if you're using xibs/size classes, I ran into a problem where the scrollView's size is stated as 600x600px no matter which device is used until the ParentViewController's viewDidLayoutSubviews is called. I had to reset the scroll view's content size again.)

After this is set up, I load the first two view controllers:

- (void)loadScrollViewWithPage:(NSUInteger)page {

    UIViewController *viewController = &lt;get your view controller&gt;;

    if (viewController.view.superview == nil) {
        [self addChildViewController:viewController];
        CGRect frame = [self.containerScrollView frame];
        frame.origin.x = CGRectGetWidth(frame)*page;
        frame.origin.y = 0;
        [viewController.view setFrame:frame];

        [self.containerScrollView addSubview:viewController.view];
        [viewController didMoveToParentViewController:self];
    }
}


Since the first two view controllers are loaded, there is no lag when the user swipes between them. When UIScrollView is scrolled, the page is scrolls to is already loaded. Once it does, I load the next one in order: 

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    CGFloat pageWidth = CGRectGetWidth(self.scrollView.frame);
    NSUInteger page = floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;

    [self loadScrollViewWithPage:page - 1];
    [self loadScrollViewWithPage:page];
    [self loadScrollViewWithPage:page + 1];
}


This way you always have the current, previous and the next view controller always ready. You could load more than 3 if the network calls you have to make take longer and the what the user is expected to scroll at.

You could unload older view controllers by calling viewController.view = nil and always only have a set number of view controllers loaded.

I created a custom protocol for the UICollectionView and set my parent controller as delegate to respond to cell clicks and navigate to the appropriate page.