Nesting a (vertical) UIPageViewController inside another (horizontal) UIPageViewcontroller
iphone, nested, objective-c, uipageviewcontroller, uiviewcontroller
Solution
I forgot to assign `dataSource` and `delegate` properties of my vertical page view controllers in
- `-pageViewController:viewControllerBeforeViewController:`
- `-pageViewController:viewControllerAfterViewController:`
Problem solved, everything works beautifully.
Problem
I have a big problem with my `UIPageViewController`. I want to present content in my app using sections and sub-sections. So, I have created "two" instances of `UIPageViewController` - horizontal (red) and vertical (blue): Earlier I said I have created "two" instances - it is not quite true - there can be tens of instances, but only 2 are presented at the same time, you know what I mean. Both controllers have `transitionStyle` set to `UIPageViewControllerTransitionStyleScroll`. The red `UIPageViewController` is responsible for horizontal scrolling between sections and blue are responsible for vertical scrolling. They both work when separated but when I put vertical `UIPageViewController` in horizontal, the vertical one stops working. My code is presented below: Horizontal `UIPageViewController` creation ``` self.mainPageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:@{UIPageViewControllerOptionInterPageSpacingKey:[NSNumber numberWithFloat:0]}]; self.mainPageViewController.dataSource = self; self.mainPageViewController.delegate = self; self.pdfDocsURLs = @[ @{@"v":[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"1v" ofType:@"pdf"]], @"h":[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"1h" ofType:@"pdf"]]}, @{@"v":[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"2v" ofType:@"pdf"]], @"h":[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"2h" ofType:@"pdf"]]}, @{@"v":[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"3v" ofType:@"pdf"]], @"h":[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"3h" ofType:@"pdf"]]}]; UIIndexedPageViewController *pvc = [[UIIndexedPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationVertical options:@{UIPageViewControllerOptionInterPageSpacingKey:[NSNumber numberWithFloat:0]}]; pvc.index = 1; PDFDocument *vdoc = [[PDFDocument alloc] initWithPDFFileURL:self.pdfDocsURLs[0][@"v"] password:nil]; PDFDocument *hdoc = [[PDFDocument alloc] initWithPDFFileURL:self.pdfDocsURLs[0][@"h"] password:nil]; PDFSinglePageViewController *svc = [[PDFSinglePageViewController alloc] initWithVerticalPDF:vdoc horizontalPDF:hdoc page:1]; [pvc setViewControllers:@[svc] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil]; [self.mainPageViewController setViewControllers:@[pvc] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil]; ``` Just to be clear, `UIIndexedPageViewController` is a subclass of UIPVC with extra `NSUInteger index` property. Its implementation is empty - it doesn't overwrite any methods. `UIPageViewController` dataSource methods ``` - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController { if(pageViewController == self.mainPageViewController) { // if horizontal UIIndexedPageViewController *ivc = (UIIndexedPageViewController *)viewController; if(ivc.index == self.pdfDocsURLs.count) return nil; UIIndexedPageViewController *pvc = [[UIIndexedPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationVertical options:@{UIPageViewControllerOptionInterPageSpacingKey:[NSNumber numberWithFloat:0]}]; pvc.index = ivc.index+1; PDFDocument *vdoc = [[PDFDocument alloc] initWithPDFFileURL:self.pdfDocsURLs[ivc.index][@"v"] password:nil]; PDFDocument *hdoc = [[PDFDocument alloc] initWithPDFFileURL:self.pdfDocsURLs[ivc.index][@"h"] password:nil]; PDFSinglePageViewController *svc = [[PDFSinglePageViewController alloc] initWithVerticalPDF:vdoc horizontalPDF:hdoc page:1]; [pvc setViewControllers:@[svc] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil]; return pvc; } else { // if vertical - THE CODE BELOW IS NEVER EXECUTED PDFSinglePageViewController *ovc = (PDFSinglePageViewController *)viewController; NSUInteger nop = 0; if(UIInterfaceOrientationIsPortrait(ovc.interfaceOrientation)) nop = ovc.verticalDoc.numberOfPages; else if(UIInterfaceOrientationIsLandscape(ovc.interfaceOrientation)) nop = ovc.horizontalDoc.numberOfPages; if(ovc.page == nop) return nil; PDFSinglePageViewController *svc = [[PDFSinglePageViewController alloc] initWithVerticalPDF:ovc.verticalDoc horizontalPDF:ovc.horizontalDoc page:ovc.page+1]; return svc; } } - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController { if(pageViewController == self.mainPageViewController) { // if horizontal UIIndexedPageViewController *ivc = (UIIndexedPageViewController *)viewController; if(ivc.index == 1) return nil; UIIndexedPageViewController *pvc = [[UIIndexedPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationVertical options:@{UIPageViewControllerOptionInterPageSpacingKey:[NSNumber numberWithFloat:0]}]; pvc.index = ivc.index-1; PDFDocument *vdoc = [[PDFDocument alloc] initWithPDFFileURL:self.pdfDocsURLs[ivc.index-2][@"v"] password:nil]; PDFDocument *hdoc = [[PDFDocument alloc] initWithPDFFileURL:self.pdfDocsURLs[ivc.index-2][@"h"] password:nil]; PDFSinglePageViewController *svc = [[PDFSinglePageViewController alloc] initWithVerticalPDF:vdoc horizontalPDF:hdoc page:1]; [pvc setViewControllers:@[svc] direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil]; return pvc; } else { // is vertical - THE CODE BELOW IS NEVER EXECUTED PDFSinglePageViewController *ovc = (PDFSinglePageViewController *)viewController; NSUInteger nop = 0; if(UIInterfaceOrientationIsPortrait(ovc.interfaceOrientation)) nop = ovc.verticalDoc.numberOfPages; else if(UIInterfaceOrientationIsLandscape(ovc.interfaceOrientation)) nop = ovc.horizontalDoc.numberOfPages; if(ovc.page == 1) return nil; PDFSinglePageViewController *svc = [[PDFSinglePageViewController alloc] initWithVerticalPDF:ovc.verticalDoc horizontalPDF:ovc.horizontalDoc page:ovc.page-1]; return svc; } } ``` So it seems that horizontal `UIPageViewController` doesn't allow the vertical one to even receive pan gesture recognizers. My question is... Is there a way to allow the vertical `UIPageViewController` to receive touches and scroll in both directions? Any help would be appreciated.