我应该 return 在 presentationIndexForPageViewController: 中为我的 UIPageViewControllerDataSource 做什么?

What should I return in presentationIndexForPageViewController: for my UIPageViewControllerDataSource?

presentationIndexForPageViewController: 的 return 值的文档说:

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

然而,这是含糊不清的。当用户滚动页面视图控制器时,它会调用此方法并期望正确的索引吗?

此外,无法保证何时 pageViewController:viewControllerBeforeViewController: and pageViewController:viewControllerAfterViewController:。文档只是提到:

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

事实上,我已经看到在某些情况下会发生缓存。例如,看起来只有当您从它向前导航两个页面时,视图控制器才会被释放。否则,它希望将其保存在缓存中,以防用户在页面视图控制器中后退。

这是否意味着我需要一种一致的方式来通过注册为 UIPageViewControllerDelegate 然后 constantly updating this value 来了解当前显示的页面?

关于 presentationCountForPageViewController:presentationIndexForPageViewController:,文档指出:

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.

因此,看起来我们只需要在调用 setViewControllers:direction:animated:completion: 之后立即 return 一个有效值。

每当我实现数据源时,我都会创建一个辅助方法 showViewControllerAtIndex:animated:,并在 属性 presentationPageIndex 中跟踪 return 的值:

@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;
}

然后您可以使用此方法显示正确的视图控制器并使所选索引显示正确的值:

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

- (IBAction)buttonTapped {
    [self showViewControllerAtIndex:3 animated:YES];
}