Reliable way to get current UIPageViewController index

I'm looking for a reliable way to track the current UIPageViewController index.

The problem is well known; Although viewControllers are displayed correctly, it is difficult to track the current index.

I thought it would be good to update this topic through the SO community, as for some reason it remains unresolved.

I looked at a lot of threads here, but most of the answers are outdated or flagged as unreliable (the result depends on whether the user was executed with a full hit or just half-scrolled, etc.)

I visited this thread, but it does not contain an explicit correct answer.

I tried:

1) Tracking the tag viewController view - link - always returns 0

2) Considering the index variable in both methods UIPageViewController, viewControllerBeforeViewController and viewControllerAfterViewControlle

its results are unpredictable, sometimes it skips one index, etc.

Has anyone come up with a good way, a reliable way to track the UIPageCiewController index to use it (like print index)?

I would appreciate both obj-c and fast implementation, but fast is the one I'm looking for.

+3
ios objective-c swift uipageviewcontroller
Apr 26 '16 at 6:57
source share
2 answers

This is for ObjC

Parentviewcontroller

 #import "PagesViewController.h" // Delegate: PageViewDelegate // Declared inside `PagesViewController` // @interface ParentViewController () <UIPageViewControllerDataSource, UIPageViewControllerDelegate, PageViewDelegate> @property (nonatomic) UIPageViewController *pageViewController; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil]; self.pageViewController.dataSource = self; self.pageViewController.view.frame = self.view.frame; // im setting page 3 as the default page // [self.pageViewController setViewControllers:[NSArray arrayWithObject:[self viewControllerAtIndex:3]] direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:nil]; [self addChildViewController:self.pageViewController]; [self.view addSubview:self.pageViewController.view]; } - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController { NSUInteger index = [(PagesViewController *)viewController index]; if (index == 0) { return nil; } index--; return [self viewControllerAtIndex:index]; } - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController { NSUInteger index = [(PagesViewController *)viewController index]; index++; if (index == 5) { return nil; } return [self viewControllerAtIndex:index]; } - (PagesViewController *)viewControllerAtIndex:(NSInteger)index { PagesViewController *vc = [[PagesViewController alloc] init]; // set delegate here.. // vc.delegate = self; // other data // vc.index = index; vc.titleLabel = [NSString stringWithFormat:@"Screen :%ld", (long)index]; return vc; } - (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController { // The number of items reflected in the page indicator. return x; } - (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController { // The selected item reflected in the page indicator. return x; } // This is what you need // - (void)viewController:(id)VC didShowWithIndex:(long)index { NSLog(@"didShowWithIndex: %ld", index); } 

PagesViewController.h

 @protocol PageViewDelegate <NSObject> - (void)viewController:(id)VC didShowWithIndex:(long)index; @end @interface PagesViewController : UIViewController @property (weak) id <PageViewDelegate> delegate; @property (nonatomic) NSInteger index; @property (nonatomic) NSString *titleLabel; @end 

PagesViewController.m

 @implementation PagesViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor blackColor]; UILabel *titleLabel = [[UILabel alloc] initWithFrame:self.view.frame]; titleLabel.textAlignment = NSTextAlignmentCenter; titleLabel.textColor = [UIColor whiteColor]; titleLabel.text = self.titleLabel; [self.view addSubview:titleLabel]; } // Trigger delegate here // - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self.delegate viewController:self didShowWithIndex:self.index]; } @end 
+2
Apr 26 '16 at 9:25
source share

Like @ 0yeoj, the proposed solution for delegating solutions is a solution. It takes a little thinking outside the box.

Let it add the IndexDelegate protocol and modify the PageContentViewController bit

 protocol IndexDelegate { func showIndex(index:Int) } import UIKit class PageContentViewController: UIViewController { @IBOutlet weak var imageView: UIImageView! var delegate:IndexDelegate? var pageIndex:Int = 0 var imageFile:String! override func viewDidLoad() { super.viewDidLoad() self.imageView.image = UIImage(named: self.imageFile) } override func viewDidAppear(animated: Bool) { self.delegate!.showIndex(self.pageIndex) } 

now in our parent view we agree with the protocol

 func showIndex(index: Int) { print(index) } 

don't forget to set yourPageContentViewControllerInstance.delegate = self and inherit the protocol YourParentViewController:UIViewController, UIPageViewControllerDataSourceDelegate, IndexDelegate {}

What is it! It works perfectly and reliably and does not lag at all!

+2
Apr 26 '16 at 9:23
source share



All Articles