0

I'm trying to create a page view controller that once you reach the last screen (right swiping) it starts over at the first, and if you scroll backward, once it hits the first screen (left swiping) it will scroll to the last.

I looked at this post: scroll in circles

but it's still stopping at the first and last screens when scrolling. Here is how my dataSource is set up:

var viewControllerList: [UIViewController]!

      func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        guard let vcIndex = viewControllerList.firstIndex(of: viewController) else {return nil}
        
        let previousIndex = vcIndex - 1
        
        guard previousIndex >= 0 else {return viewControllerList.last}
        
        guard viewControllerList.count > previousIndex else { return nil}
        
        return viewControllerList[previousIndex]
}

  func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        guard let vcIndex = viewControllerList.firstIndex(of: viewController) else {return nil}
        
        let nextIndex = vcIndex + 1
        
        guard viewControllerList.count != nextIndex else {return nil}
        
        guard viewControllerList.count > nextIndex else
        {
            return viewControllerList.first}
    
        
        return viewControllerList[nextIndex]
}

Any help is appreciated!!

SwiftyJD
  • 5,257
  • 7
  • 41
  • 92
  • 2
    It's because of the lines where you `return nil`. As long as you do that, it means "it is impossible to go any further in this direction". But I believe your requirement is that it is _always_ possible to go further in _either_ direction. :) – matt Aug 19 '20 at 22:12
  • @matt that was it! Thanks a lot. I want to mark this as correct answer. – SwiftyJD Aug 19 '20 at 22:17
  • I'll just write the comment directly as an answer, then. – matt Aug 19 '20 at 23:14
  • Hi. I have the same issue. Could you please say what you did instead return nil? – Abrcd18 Apr 06 '23 at 10:15

2 Answers2

1

Your index logic is faulty.

For example in the before logic you check

previousIndex >= 0

That means you would never get to index 0 in the reverse direction. You need in that check

previousIndex > -1 

to ensure that you can proceed in the case of a 3 page array in the index order

2,1,0,2…

Similarly in the forward direction you use

guard viewControllerList.count != nextIndex else {return nil}

Effectively stopping the sequence when you want to return the first controller

guard viewControllerList.count != nextIndex else {return viewControllerList.first}

Ensure your logic can give you the indexes in the 3 page case.

0,1,2,0…
Warren Burton
  • 17,451
  • 3
  • 53
  • 73
1

It's because of the lines where you return nil. As long as you do that, it means "it is impossible to go any further in this direction". But I believe your requirement is that it is always possible to go further in either direction.

matt
  • 515,959
  • 87
  • 875
  • 1,141