Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to add two view controllers in UIPageViewcontroller

I m using UIPageViewController on iPad where I need to show a firstviewController in the first page and ContentViewController in the next page in landscape.

If I set the NSArray with two viewControllers the app is crashes at [self.pagviewController setViewController:] with the following exception:

The number of provided view controllers (2) doesn't match the number required (1) for the requested spine location (UIPageViewControllerSpineLocationMin)

Below is the code:

#pragma mark - UIPageViewControllerDataSource Methods  - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController        viewControllerBeforeViewController:(UIViewController *)viewController {     NSUInteger currentIndex = [self.modelArray indexOfObject:[(ContentViewController *)viewController textContents]];     if(currentIndex == 0)     {         return nil;     }     ContentViewController *contentViewController = [[ContentViewController alloc] init];     contentViewController.textContents = [self.modelArray objectAtIndex:currentIndex - 1];     return contentViewController; }  - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController        viewControllerAfterViewController:(UIViewController *)viewController {     NSUInteger currentIndex = [self.modelArray indexOfObject:[(ContentViewController *)viewController textContents]];     if(currentIndex == self.modelArray.count-1)     {         return nil;     }     ContentViewController *contentViewController = [[ContentViewController alloc] init];     contentViewController.textContents = [self.modelArray objectAtIndex:currentIndex + 1];      return contentViewController; }     //#pragma mark - UIPageViewControllerDelegate Methods  - (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController                    spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation {     if(UIInterfaceOrientationIsPortrait(orientation))     {         //Set the array with only 1 view controller         UIViewController *currentViewController = [self.pageViewController.viewControllers objectAtIndex:0];         NSArray *viewControllers = [NSArray arrayWithObject:currentViewController];          [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];          //Important- Set the doubleSided property to NO.         self.pageViewController.doubleSided = NO;         //Return the spine location         return UIPageViewControllerSpineLocationMin;     }     else     {         NSArray *viewControllers = nil;         ContentViewController *currentViewController = [self.pageViewController.viewControllers objectAtIndex:0];          NSUInteger currentIndex = [self.modelArray indexOfObject:[(ContentViewController *)currentViewController textContents]];         if(currentIndex == 0 || currentIndex %2 == 0)         {             UIViewController *nextViewController = [self pageViewController:self.pageViewController viewControllerAfterViewController:currentViewController];             viewControllers = [NSArray arrayWithObjects:currentViewController, nextViewController, nil];         }         else         {             UIViewController *previousViewController = [self pageViewController:self.pageViewController viewControllerBeforeViewController:currentViewController];             viewControllers = [NSArray arrayWithObjects:previousViewController, currentViewController, nil];         }         //Now, set the viewControllers property of UIPageViewController         [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];          return UIPageViewControllerSpineLocationMid;     } } - (void)viewDidLoad {     [super viewDidLoad];      appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];     //Instantiate the model array     self.modelArray = [[NSMutableArray alloc] init];     self.vcs = [[NSMutableArray alloc]init];      for (int index = 1; index <= 2 ; index++)     {         [self.modelArray addObject:[NSString stringWithFormat:@"Page %d",index]];     }      //Step 1     //Instantiate the UIPageViewController.     self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl                                                               navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];     //Step 2:     //Assign the delegate and datasource as self.     self.pageViewController.delegate = self;     self.pageViewController.dataSource = self;      //Step 3:     //Set the initial view controllers.      appDelegate.contentViewController.textContents = [self.modelArray objectAtIndex:0];       NSArray *viewControllers = [NSArray arrayWithObjects:appDelegate.firstViewController,appDelegate.contentViewController,nil];     [self.pageViewController setViewControllers:viewControllers                                       direction:UIPageViewControllerNavigationDirectionForward                                        animated:NO                                      completion:nil];      //Step 4:     //ViewController containment steps     //Add the pageViewController as the childViewController     [self addChildViewController:self.pageViewController];      //Add the view of the pageViewController to the current view     [self.view addSubview:self.pageViewController.view];      //Call didMoveToParentViewController: of the childViewController, the UIPageViewController instance in our case.     [self.pageViewController didMoveToParentViewController:self];      //Step 5:     // set the pageViewController's frame as an inset rect.     CGRect pageViewRect = self.view.bounds;     pageViewRect = CGRectInset(pageViewRect, 40.0, 40.0);     self.pageViewController.view.frame = pageViewRect;      //Step 6:     //Assign the gestureRecognizers property of our pageViewController to our view's gestureRecognizers property.     self.view.gestureRecognizers = self.pageViewController.gestureRecognizers; } 
like image 335
user578386 Avatar asked Apr 04 '13 09:04

user578386


People also ask

How do I switch between view controllers?

From the Library, add a button to the first View Controller and name the button, for example: Show Second View . Select the button, press and hold the Control key on the keyboard and drag from the button to the second View Controller.

Does SwiftUI use viewcontrollers?

SwiftUI works seamlessly with the existing UI frameworks on all Apple platforms. For example, you can place UIKit views and view controllers inside SwiftUI views, and vice versa.


2 Answers

The problem is you passing an array containing two view controllers to the page view controller while it expects one at a time, change your array to be like this :

NSArray *viewControllers = @[appDelegate.firstViewController]; 

You will pass one of the views but viewControllerAfterViewController and viewControllerBeforeViewController will handle the rest.

like image 105
Ben Avatar answered Sep 21 '22 20:09

Ben


Ah..Finally got solution for this same issue.., it may helps you..

When we set the spine location to UIPageViewControllerSpineLocationMid, the doubleSided property of the pageViewController is automatically set to YES. This means that the content on page front will not partially show through back. But when this property is set to NO, the content on page front will partially show through back, giving the page a translucent kind of effect. So, in the portrait orientation, we have to set the value to NO, otherwise it would result in an exception.

So in your UIPageviewcontroller delegate method, in else part add this doubleSided property as YES when you return spineLocation as UIPageViewControllerSpineLocationMid

self.pageViewController.doubleSided = YES; return UIPageViewControllerSpineLocationMid; 
like image 25
wesley Avatar answered Sep 21 '22 20:09

wesley