Reputation: 638
I am using UIPageViewController in my app with the following methods:
-(ChildViewController *)viewControllerAtIndex:(NSUInteger)index {
if (([self.pageImages count] == 0) || (index >= [self.pageImages count])) {
return nil;
}
// Create a new view controller and pass suitable data.
ChildViewController *pageContentViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"ChildViewController"];
pageContentViewController.imageFile = self.pageImages[index];
pageContentViewController.bodyText = self.pageBody[index];
pageContentViewController.pageIndex = index;
NSLog(@"Index: %i", index);
return pageContentViewController;
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
NSUInteger index = ((ChildViewController*) viewController).pageIndex;
if ((index == 0) || (index == NSNotFound)) {
return nil;
}
index--;
return [self viewControllerAtIndex:index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
NSUInteger index = ((ChildViewController*) viewController).pageIndex;
if (index == NSNotFound || (index == [self.pageImages count])) {
return nil;
}
index++;
return [self viewControllerAtIndex:index];
}
The problem I am having is that even though the pageViewController is working correctly, when I try to NSLog the index of the page I get some strange values. When I am going forward, the index increments correctly but when I try to go back a page the index jumps instead of decrementing as expected.
Here is the console read-out:
2015-01-02 16:11:13.808 iPregrancy+[12495:1837301] Index: 0
2015-01-02 16:11:15.305 iPregrancy+[12495:1837301] Index: 1
2015-01-02 16:11:15.677 iPregrancy+[12495:1837301] Index: 2
2015-01-02 16:11:17.071 iPregrancy+[12495:1837301] Index: 3
2015-01-02 16:11:18.356 iPregrancy+[12495:1837301] Index: 4
2015-01-02 16:11:20.006 iPregrancy+[12495:1837301] Index: 5
2015-01-02 16:11:21.806 iPregrancy+[12495:1837301] Index: 2
2015-01-02 16:11:32.075 iPregrancy+[12495:1837301] Index: 5
2015-01-02 16:11:33.458 iPregrancy+[12495:1837301] Index: 2
2015-01-02 16:11:35.708 iPregrancy+[12495:1837301] Index: 5
2015-01-02 16:11:36.943 iPregrancy+[12495:1837301] Index: 2
Any ideas/suggestions?
Upvotes: 1
Views: 491
Reputation: 21536
Are you using transition style UIPageViewControllerTransitionStyleScroll
? If so, I think the behaviour is due to the UIPageViewController caching the view controllers.
Say you are on the page with index 3, and you swipe left. The PVC will request (through viewControllerAfterViewController
) the VC after index 3. Your code returns the VC at index 4. But the page view controller also requests the VC after index 4 (even before you start to swipe). So you return index 5 - but this is not displayed by the PVC unless you swipe left again.
If instead you swipe right (whilst it is still displaying index 4), it still has a reference to the VC that comes before index 4 (i.e. index 3), so it displays that. But, again, it also requests the VC before index 3 - so you return the page at index 2 (but this is not displayed unless you swipe right a second time).
The result is that, if you swap back and forth between index 3 and index 4, the VCs you will see being requested are index 2 and index 5 - as per your log.
I assume the page view controller does this "pre-emptive loading" in order to avoid delay if the user keeps swiping rapidly in the same direction. But, to conclude, I don't think what you have observed is anything to worry about.
EDIT
If you want to keep track of the index that is currently being displayed, use the willTransitionToViewControllers:
and didFinishAnimating:
delegate methods. Something like:
-(void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers {
if ([pendingViewControllers[0] isKindOfClass:[ChildViewController class]]) {
ChildViewController *nextVC = (ChildViewController *)pendingViewControllers[0];
self.nextIndex = nextVC.pageIndex;
}
}
-(void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed {
if (completed) {
// transition to next VC completed successfully
self.currentIndex = self.nextIndex;
} else {
// transition was aborted
self.nextIndex = self.currentIndex;
}
}
You will need to add properties for currentIndex
and nextIndex
, and also to set the delegate
of the page view controller (in the same place as you currently set the dataSource
).
Upvotes: 3