Search code examples
iosobjective-cxcodeuipageviewcontroller

PageViewController before and after called twice and indexing not count true


- (void)viewDidLoad {
self.pageController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pageController.dataSource = self;
[[self.pageController view] setFrame:CGRectMake(0, 0, self.viewParent.frame.size.width, self.viewParent.frame.size.height)];
initialViewController = [self viewControllerAtIndex:[[NSUserDefaults standardUserDefaults] integerForKey:@"indexAllQuestion"]];
viewControllers = [NSArray arrayWithObject:initialViewController];

[self.pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
[self  addChildViewController:self.pageController];
[[self viewParent] addSubview:[self.pageController view]];
[self.pageController didMoveToParentViewController:self];
self.pageController.delegate = self;
self.pageController.dataSource = self;
}


- (AllComponentQuestionViewController *)viewControllerAtIndex:(NSUInteger)index {
current_question = self.all_question_keys[index];
AllComponentQuestionViewController *childViewController = [[AllComponentQuestionViewController alloc] initCurrent_question:current_question initCurrent_worksheet:current_worksheet iniTotalQuestion:maxDataCount];

[childSwipeVC replaceObjectAtIndex:index withObject:childViewController];
childViewController.indexChild = index;
return childViewController;}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {
NSUInteger index = [(AllComponentQuestionViewController *)viewController indexChild];
if ((index == NSNotFound) || index <= 0) {
    index = 0;
    return nil;
}
else{
    index--;
    return [self viewControllerAtIndex:index];
}
}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
NSUInteger index = [(AllComponentQuestionViewController *)viewController indexChild];
if (index >= maxDataCount) {
    index = maxDataCount;
    return nil;
}
else{
    index++;
    return [self viewControllerAtIndex:index];
}}

http://pasted.co/de8d5246 this link same like that

The case is:

  1. Swipe right from index 0 to index 1
  2. the index increase index to 2, so my index +2
  3. if i swipe again it will +1
  4. and tell if now i'm in index 8, i swipe left
  5. the index will decrease to -6, so my index -2
  6. and if i swipe left again it will index-- or index = index - 2

need help in advance, stuck in here in a week ago Thank You


Solution

  • viewControllerAfterViewController: and viewControllerBeforeViewController: are UIPageViewControllerDataSource methods, which are invoked by UIPageViewController's internal controller

    The reason why those methods are called twice with 1 swipe, is that, for example, if you swipe to the right (or go forward), it will prepare next view controller and another one in advance for you, so therefore, if you are needed to have exact index that user is currently on, you should probably need to have delegate methods for getting the current index when swiping, like:

    Objective-C:

    - (void)pageViewController:(UIPageViewController *)pageViewController 
    willTransitionToViewControllers:(NSArray<UIViewController *> *)pendingViewControllers;
    

    Swift 4:

    func pageViewController(_ pageViewController: UIPageViewController,
                            willTransitionTo pendingViewControllers: [UIViewController])
    

    and

    Objective-C:

    - (void)pageViewController:(UIPageViewController *)pageViewController 
            didFinishAnimating:(BOOL)finished 
       previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers 
           transitionCompleted:(BOOL)completed;
    

    Swift 4:

    func pageViewController(_ pageViewController: UIPageViewController,
                            didFinishAnimating finished: Bool,
                            previousViewControllers: [UIViewController],
                            transitionCompleted completed: Bool)
    

    For example, user can swipe to the right, but the transition will not fall through, and the pageViewController swipe will return to previous index automatically, therefore you need to use completed param to see if index is changed or not, etc..

    Read more here: https://developer.apple.com/reference/uikit/uipageviewcontrollerdelegate/1614090-pageviewcontroller?language=objc