title: How to implement UIPageViewController that utilizes multiple ViewControllers
body: <p>I've been working on a simple test app to learn the ins and outs of the UIPageViewController.  I have it working but I'm not convinced my execution is the best way.  I hope some of you can point me in the right direction.</p>
  
  <p>To get a basic understanding I used this tutorial as a starting point.
  <a href="http://www.appcoda.com/uipageviewcontroller-storyboard-tutorial/" rel="noreferrer">http://www.appcoda.com/uipageviewcontroller-storyboard-tutorial/</a></p>
  
  <p>The tutorial creates an app that uses one <code>viewController</code> for each of the pages presented by the <code>UIPageViewController</code>.  However I need to utilize the UIPageViewController to scroll thru pages that have completely different layouts.  Therefore to take the tutorial a step further I created an master-detail application that uses the UIPageViewController in the detail view to display three different view controllers.  I stuck with just displaying images and labels for this test app, but the app I am currently building has three viewControllers that will contain either a tableview, imageView and textViews, or some textFields.</p>
  
  <p>Here is the storyboard for my test app.</p>
  
  <p><img src="https://i1290.photobucket.com/albums/b538/7eleven3/ScreenShot2014-02-07at64412PM_zpsa64a19f6.png" alt="Storyboard"></p>
  
  <p>I use the <code>DetailViewController</code> as the data source for the <code>PageViewController</code>. In <code>viewDidLoad</code> of  the DVC I establish the labels and images that will be used in the three content view controllers <code>firstViewController</code>, <code>secondViewController</code>, and <code>thirdViewController</code> in this manner.</p>
  
  <pre><code>if ([[self.detailItem description] isEqualToString:@"F14's"]) {
      //Here the page titles and images arrays are created 
      _pageTitles = @[@"Grim Reapers", @"Breakin the Barrier!", @"Top Gun"];
      _pageImages = @[@"F14_Grim.jpg", @"F14boom.jpg", @"F14_topgun.jpg"];
  
      //Here I call a method to instantiate the viewControllers 
      FirstController *selectedController = [self viewControllerAtIndex:0];
      SecondController *nextController = [self viewControllerAtIndex:1];
      ThirdController *lastController = [self viewControllerAtIndex:2];
      [_vc addObject:selectedController];
      [_vc addObject:nextController];
      [_vc addObject:lastController];
      _vc1 = @[selectedController];
  
  
  } else if ([[self.detailItem description] isEqualToString:@"F35's"]){
      //code is above is repeated
  </code></pre>
  
  <p>Below is the method to instantiate the viewControllers</p>
  
  <pre><code>- (UIViewController *)viewControllerAtIndex:(NSUInteger)index
  {
      if (([self.pageTitles count] == 0) || (index &gt;= [self.pageTitles count])) {
          return nil;
      }
  
      // Create a new view controller and pass suitable data.
      if (index == 0) {
          FirstController *fvc = [self.storyboard instantiateViewControllerWithIdentifier:@"FirstPageController"];
          fvc.imageFile = self.pageImages[index];
          fvc.titleText = self.pageTitles[index];
          fvc.pageIndex = index;
          if ([_vc count]) {
               //Here I have to replace the viewController each time it is recreated
               [_vc replaceObjectAtIndex:0 withObject:fvc];
          }
          return fvc;
      } else if (index == 1) {
  //Code is repeated for remaining viewControllers
  </code></pre>
  
  <p>The code in <code>viewDidLoad</code> is one area I feel I am doing unnecassary work.  I don't believe I need to instantiate all three view controllers upon loading the DVC, but I didn't know how else to provide an array for the UIPageViewControllerDataSource protocol methods (<code>viewControllerBeforeViewController</code> and <code>viewControllerAfterViewController</code>).</p>
  
  <p>Here is the <code>viewControllerBefore..</code> method.</p>
  
  <pre><code>- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
  {
  
      NSUInteger index = [_vc indexOfObject:viewController];
  
      if ((index == 0) || (index == NSNotFound)) {
          return nil;
      }
  
      index--;
  
      //notice here I call my instantiation method again essentially duplicating work I have already done!
      return [self viewControllerAtIndex:index];
  }
  </code></pre>
  
  <p>In summary it seems that I am unnecassarily recreating the view controllers with every swipe from from one page to another.  Is this just how the pageViewController works or have I way over complicated the process.  Any input would be great!</p>
  
  <p><strong><em>SOLUTION</em></strong></p>
  
  <p>Matt suggested an incredibly simple solution in using <strong><em>identifiers</em></strong>.  In my Storyboard i simply checked the box that uses my already implemented Storyboard identifier as the Restoration Identifier</p>
  
  <p><img src="https://i1290.photobucket.com/albums/b538/7eleven3/ScreenShot2014-02-08at30842PM_zps3a8ff9e4.png" alt="RestorationId"></p>
  
  <p>Then in <code>viewDidLoad</code> rather than creating an array of viewControllers, simply create an array of strings that match the restoration identifiers.</p>
  
  <pre><code>if ([[self.detailItem description] isEqualToString:@"F14's"]) {
      _pageTitles = @[@"Grim Reapers", @"Breakin the Barrier!", @"Top Gun"];
      _pageImages = @[@"F14_Grim.jpg", @"F14boom.jpg", @"F14_topgun.jpg"];
      FirstController *selectedController = [self viewControllerAtIndex:0];
      [_vc addObject:@"FirstPageController"];
      [_vc addObject:@"SecondPageController"];
      [_vc addObject:@"ThirdPageController"];
      _vc1 = @[selectedController];
  </code></pre>
  
  <p>Finally to determine the index in the delegate methods do this rather than what I was doing before:</p>
  
  <pre><code>NSString * ident = viewController.restorationIdentifier;
  NSUInteger index = [_vc indexOfObject:ident];
  </code></pre>
  
  <p>It now works without having to unnecessarily instantiate the view controllers.</p>
  
  <p>As a last note if anyone is using exactly what I have here you can get rid of the following snippet from the <code>viewControllerAtIndex:</code> method.</p>
  
  <pre><code>if ([_vc count]) {
       //Here I have to replace the viewController each time it is recreated
       [_vc replaceObjectAtIndex:0 withObject:fvc];
  }
  </code></pre>