16

I have spent almost 8 hours finding out how to jump to a particular page number in UIPageViewController... below is what my project looks like

I want to make an app which looks like Ibooks---

I have taken the help from the code presented here - http://www.ioslearner.com/tag/uipageviewcontroller-sample-code/

I have made a plist and UITableView , I select the value from TableView and display the same on webView placed on UIPAgeiewController, but the problem is that only the page in web view changes and not the actual page number of the UIPageViewController....

If I narrow down my question it would look like --- is there a way to switch between page numbers in UIPageViewController.... ???

A K
  • 295
  • 1
  • 4
  • 19
  • why is this tagged [apex-code]? – vikingosegundo Jul 05 '12 at 12:49
  • by any chance do you have an idea how to solve above problem ? @vikingosegundo – A K Jul 05 '12 at 12:51
  • as I said below your other question: I never worked with it, but this looks promising: http://stackoverflow.com/questions/7208871/is-it-possible-to-turn-page-programmatically-in-uipageviewcontroller – vikingosegundo Jul 05 '12 at 12:56
  • see? once the tagging is better, you got more attention and one of the most successful [objective-c] and [ios] answerers is answering your question. – vikingosegundo Jul 05 '12 at 13:02
  • Possible duplicate of [UIPageViewController, how do I correctly jump to a specific page without messing up the order specified by the data source?](http://stackoverflow.com/questions/13633059/uipageviewcontroller-how-do-i-correctly-jump-to-a-specific-page-without-messing) – jokeman Oct 18 '16 at 17:37

6 Answers6

6

You have to instantiate the view controller(s) that manage the page(s) you want to jump to and then call the page view controller's setViewControllers:direction:animated:completion: method, passing the new view controller(s).

Ole Begemann
  • 135,006
  • 31
  • 278
  • 256
  • I am getting the idea Ole of what you are saying.. but not completely .. can you please elaborate the same for me... I am kind of new to Xcode and have spend almost 15 hour over the same issue.. Thanks in Advance – A K Jul 05 '12 at 13:34
  • Look at the question vikingosegundo linked to in his comment. One answer to it even contains sample code. – Ole Begemann Jul 05 '12 at 13:59
6

Swift Code:

func goToPage(index: Int) {
    if index < viewControllers.count {
        pageVC!.setViewControllers([viewControllers[index]], direction: .Forward, animated: true, completion: nil)
    }
}
Cullen SUN
  • 3,517
  • 3
  • 32
  • 33
  • 1
    this is not really correct. "viewControllers" is NOT "all of the pages". it is ONLY the currently showing page. – Fattie Jun 27 '20 at 21:24
3

Here is another example how to jump to page with parsed Index:

-(void)gotoPage:(int)index{


    SinglePageViewController *viewController = [self viewControllerAtIndex:index];

    UIPageViewControllerNavigationDirection direction;
    if(_curIndex <= index){
        direction = UIPageViewControllerNavigationDirectionForward;
    }
    else
    {
        direction = UIPageViewControllerNavigationDirectionReverse;
    }


    if(_curIndex < index)
    {
        for (int i = 0; i <= index; i++)
        {
            if (i == index) {
                [self.pageViewController setViewControllers:@[viewController]
                                          direction:direction
                                           animated:YES
                                         completion:nil];
            }
            else
            {
                [self.pageViewController setViewControllers:@[[self viewControllerAtIndex:i]]
                                          direction:direction
                                           animated:NO
                                         completion:nil];

            }
        }
    }
    else
    {
        for (int i = _curIndex; i >= index; i--)
        {
            if (i == index) {
                [self.pageViewController setViewControllers:@[viewController]
                                          direction:direction
                                           animated:YES
                                         completion:nil];
            }
            else
            {
                [self.pageViewController setViewControllers:@[[self viewControllerAtIndex:i]]
                                          direction:direction
                                           animated:NO
                                         completion:nil];

            }
        }
    }

    _curIndex = index;
}
Miki
  • 903
  • 7
  • 26
2

I use this function (I'm always in landscape, 2 page mode)

-(void) flipToPage:(NSString * )index {


int x = [index intValue];
LeafletPageContentViewController *theCurrentViewController = [self.pageViewController.viewControllers   objectAtIndex:0];

NSUInteger retreivedIndex = [self indexOfViewController:theCurrentViewController];

LeafletPageContentViewController *firstViewController = [self viewControllerAtIndex:x];
LeafletPageContentViewController *secondViewController = [self viewControllerAtIndex:x+1 ];


NSArray *viewControllers = nil;

viewControllers = [NSArray arrayWithObjects:firstViewController, secondViewController, nil];


if (retreivedIndex < x){

    [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];

} else {

    if (retreivedIndex > x ){

        [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionReverse animated:YES completion:NULL];
      } 
    }
} 

Maybe you need this too

- (LeafletPageContentViewController *)viewControllerAtIndex:(NSUInteger)index {   

    if (([self.modelArray count] == 0) || (index >= [self.modelArray count])) {
        return nil;
    }
    LeafletPageContentViewController *dataViewController;
    dataViewController = [[LeafletPageContentViewController alloc]initWithNibName:@"LeafletPageContentViewController" bundle:nil];

    dataViewController.dataObject = [self.modelArray objectAtIndex:index];
    return dataViewController;

}
jcesarmobile
  • 51,328
  • 11
  • 132
  • 176
  • Yes, I use this method on an app. Do you have any problem? – jcesarmobile Dec 19 '12 at 09:47
  • ya, in my code this line"[self.pageViewController.viewControllers objectAtIndex:0]; is not working. – iPhone Programmatically Dec 19 '12 at 09:53
  • change self.pageViewController to the name of your pageViewController, and or try with _pageViewController instead self.pageViewController – jcesarmobile Dec 19 '12 at 11:24
  • thats not the issue, viewControllers are nil, but when called by delegates it works but when called by button it shows null value. – iPhone Programmatically Dec 19 '12 at 11:28
  • I don't know, it works for me, and I use [self.pageViewController.viewControllers objectAtIndex:0]; for jump to page, page back, page forward and some other options without problems, it shouldn't be null – jcesarmobile Dec 19 '12 at 11:44
  • Can you tell from where are you giving value to index in method. – iPhone Programmatically Dec 19 '12 at 12:31
  • Do you mean this index "-(void) flipToPage:(NSString * )index" <-- ? this is the page I want to go, (allways even because I'm always in two page mode) – jcesarmobile Dec 19 '12 at 13:11
  • that i know sir, but from where it gets value, because [self.pageViewController.viewControllers objectAtIndex:0] is returning nothing. It is clear that when delegate is called it gives value else not if you call it by other means. – iPhone Programmatically Dec 19 '12 at 13:20
  • you give it the value when you call the method. for example [self flipToPage:@"2"];, then I get the integer value with int x = [index intValue];. and to get the viewControllers I use LeafletPageContentViewController *firstViewController = [self viewControllerAtIndex:x]; LeafletPageContentViewController *secondViewController = [self viewControllerAtIndex:x+1 ]; – jcesarmobile Dec 19 '12 at 13:26
  • [self.pageViewController.viewControllers objectAtIndex:0]; is used to know the current page of the pageViewController and change the animation of the pageChange – jcesarmobile Dec 19 '12 at 13:28
  • I know bro, but this line "[self.pageController.viewControllers lastObject];" only is not getting value, when called in this method. – iPhone Programmatically Dec 19 '12 at 13:31
  • I don't use [self.pageController.viewControllers lastObject]; I use [self.pageViewController.viewControllers objectAtIndex:0] – jcesarmobile Dec 19 '12 at 13:33
  • So try this -(void) flipToPage:(NSString * )index { int x = [index intValue]; LeafletPageContentViewController *firstViewController = [self viewControllerAtIndex:x]; LeafletPageContentViewController *secondViewController = [self viewControllerAtIndex:x+1 ]; NSArray *viewControllers = nil; viewControllers = [NSArray arrayWithObjects:firstViewController, secondViewController, nil]; [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL]; } – jcesarmobile Dec 19 '12 at 13:36
  • did that already, just tried it is not moving to next view, am also using two page mode, don't know why this thing not returning value. – iPhone Programmatically Dec 19 '12 at 13:41
  • I have added my viewControllerAtIndex method too, maybe yours is wrong. BTW, change the LeafletPageContentViewController to the class of the viewControllers that you use for each page. – jcesarmobile Dec 19 '12 at 13:46
  • the array which is holding the values returns null when called manually by button. – iPhone Programmatically Dec 19 '12 at 13:46
  • dataObject is an object I created on my LeafletPageContentViewController, it can be any kind of object, it deppends on what you need. It have to be the same class of the objects you have on the modelArray (the dataSource of your pageViewController) – jcesarmobile Dec 19 '12 at 13:58
  • please can you show where you create this object, i didn't understand. – iPhone Programmatically Dec 19 '12 at 14:01
  • just create a new project with the pageViewController template. The DataViewController comes with the dataObject – jcesarmobile Dec 19 '12 at 14:11
  • Please check my this question link, you can judge better the issue here. http://stackoverflow.com/questions/13967558/uipageviewcontroller-the-array-containing-the-view-controllers-returns-null-wh – iPhone Programmatically Dec 20 '12 at 08:28
2

@milijan answer worked great. Here is the swift version of his answer:

func jumptoPage(index : Int) {

    let vc = viewControllerAtIndex(index)
    let direction : UIPageViewControllerNavigationDirection!

    if currentIndex < index {
        direction = UIPageViewControllerNavigationDirection.Forward
    }
    else {
        direction = UIPageViewControllerNavigationDirection.Reverse
    }

    if (currentIndex < index) {
        for var i = 0; i <= index; i++ {
            if (i == index) {
                self.newPageViewController.setViewControllers([vc], direction: direction, animated: true, completion: nil)
            }
            else {
                self.newPageViewController.setViewControllers([viewControllerAtIndex(i)], direction: direction, animated: false, completion: nil)
            }
        }
    }
    else {
        for var i = currentIndex; i >= index; i = i - 1 {
            if i == index {
                self.newPageViewController.setViewControllers([vc], direction: direction, animated: true, completion: nil)
            }
            else {
                self.newPageViewController.setViewControllers([viewControllerAtIndex(i)], direction: direction, animated: false, completion: nil)
            }
        }
    }
 currentIndex = index
}
brl214
  • 527
  • 1
  • 6
  • 16
2

modern solution:

you always need this simple function:

var currentIndex: Int {
    if let visibleViewController = viewControllers?.first,
       let ci = pages.firstIndex(of: visibleViewController) {
        return ci
    }
    else {
        return 0
    }
}

animate to any page:

public func go(toIndex: Int) {
    setViewControllers(
        [pages[toIndex]],
        direction: ((currentIndex < toIndex) ? .forward : .reverse),
        animated: true)
}
Fattie
  • 27,874
  • 70
  • 431
  • 719