Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nesting a (vertical) UIPageViewController inside another (horizontal) UIPageViewcontroller

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):

scheme

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.

like image 457
akashivskyy Avatar asked Feb 23 '13 11:02

akashivskyy


1 Answers

I forgot to assign dataSource and delegate properties of my vertical page view controllers in

  • -pageViewController:viewControllerBeforeViewController:
  • -pageViewController:viewControllerAfterViewController:

Problem solved, everything works beautifully.

like image 160
akashivskyy Avatar answered Nov 15 '22 05:11

akashivskyy