Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What should I return in presentationIndexForPageViewController: for my UIPageViewControllerDataSource?

The documentation for the return value of presentationIndexForPageViewController: says:

Returns the index of the selected item to be reflected in the page indicator.

However, this is vague. Will it call this method and expect the proper index as the user scrolls through the page view controller?

Furthermore, there are no guarantees as to when pageViewController:viewControllerBeforeViewController: and pageViewController:viewControllerAfterViewController:. The documentation just mentions:

[An] object [provides] view controllers to the page view controller on an as-needed basis, in response to navigation gestures.

In fact, I have seen caching happening under certain circumstances. For example, it looks like a view controller will only get deallocated if you navigate two pages forward from it. Otherwise it wants to keep it in cache in case the user goes backwards in the page view controller.

Does this then mean that I need a consistent way to know which page is currently being displayed by registering as the UIPageViewControllerDelegate and then constantly updating this value?

like image 217
Senseful Avatar asked Apr 20 '15 20:04

Senseful


1 Answers

Regarding presentationCountForPageViewController: and presentationIndexForPageViewController:, the documentation states:

Both of these methods are called after the setViewControllers:direction:animated:completion: method is called. After gesture-driven navigation, these methods are not called. The index is updated automatically and the number of view controllers is expected to remain constant.

Therefore, it looks like we only need to return a valid value immediately after setViewControllers:direction:animated:completion: is called.

Whenever I implement the data source, I create a helper method, showViewControllerAtIndex:animated:, and keep track of the value to return in a property presentationPageIndex:

@property (nonatomic, assign) NSInteger presentationPageIndex;
@property (nonatomic, strong) NSArray *viewControllers; // customize this as needed

// ...

- (void)showViewControllerAtIndex:(NSUInteger)index animated:(BOOL)animated {
    self.presentationPageIndex = index;
    [self.pageViewController setViewControllers:@[self.viewControllers[index]] direction:UIPageViewControllerNavigationDirectionForward animated:animated completion:nil];
}

#pragma mark - UIPageViewControllerDataSource

- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController {
    return self.presentationPageIndex;
}

You can then use this method to show the proper view controller and have the selected index display the correct value:

- (void)viewDidLoad {
    [super viewDidLoad];
    [self showViewControllerAtIndex:0 animated:NO];
}

- (IBAction)buttonTapped {
    [self showViewControllerAtIndex:3 animated:YES];
}
like image 118
Senseful Avatar answered Oct 24 '22 19:10

Senseful