UIPageViewController: return the current visible view UIPageViewController: return the current visible view ios ios

UIPageViewController: return the current visible view


You should manually keep track of the current page.

The delegate method pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted: will tell you when to update that variable. The last argument of the method transitionCompleted: can tell you whether a user completed a page turn transition or not.

Then, you can get the currently presented View Controller by doing

self.viewControllers?.first


As of iOS 6 I've found that the viewControllers property of UIPageViewController constantly updates so that it will always hold the one view controller that represents the current page, and nothing else. Thus, you can access the current page by calling viewControllers[0] (Assuming you only show one view controller at a time).

The viewController array only updates once the page "locks" into place, so if a user decides to partially reveal the next page it doesn't become the "current" page unless they complete the transition.

If you want to keep track of the "page numbers" assign your view controllers an index value as you create them through the UIPageViewController datasource methods.


So for example:

-(void)autoAdvance    {    UIViewController *currentVC = self.viewControllers[0];    NSUInteger currentIndex = [myViewControllers indexOfObject:currentVC];    if ( currentIndex >= (myViewControllers.count-1) ) return;    [self setViewControllers:@[myViewControllers[ currentIndex+1 ]]        direction:UIPageViewControllerNavigationDirectionForward        animated:YES        completion:nil];    }-(NSInteger)presentationIndexForPageViewController:                         (UIPageViewController *)pageViewController    {    // return 0;    UIViewController *currentVC = self.viewControllers[0];    NSUInteger currentIndex = [myViewControllers indexOfObject:currentVC];    return currentIndex;    }

But note the comments that this is unreliable.


Unfortunately, all above methods didn't help me. Nevertheless, I have found the solution by using tags. May be it's not the best, but it works and hope it helps someone:

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed {    if (completed) {        int currentIndex = ((UIViewController *)self.pageViewController.viewControllers.firstObject).view.tag;        self.pageControl.currentPage = currentIndex;    }}

In Swift: (thanks to @Jessy)

func pageViewController(pageViewController: UIPageViewController,    didFinishAnimating finished: Bool,    previousViewControllers: [UIViewController],    transitionCompleted completed: Bool){    guard completed else { return }    self.pageControl.currentPage = pageViewController.viewControllers!.first!.view.tag}

Example: gist