0
votes

I'm developing an iOS app and I imeplementes a Demo Tour for the app using UIPageViewController, on each view controller I show an image and a video, but the methods

 pageViewController:ViewControllerBeforeViewController
 pageViewController:ViewControllerAfterViewController

are not working properly, sometimes it jumps to another page that is not the next one or the previous one. It only occurs when I use swipe gestures to pass the pages if I tap on the page indicator (UIPageControl) it works correctly.

My code:

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
  NSUInteger index = ((DemoTourViewController*) viewController).pageIndex;

  if (index == NSNotFound)
    return nil;

  // If the current page is the first one then go back to the last one
  if (index == 0)
    index = [self.pageTitles count];

  index--;
  return [self viewControllerAtIndex:index];
 }

 - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
 {
  NSUInteger index = ((DemoTourViewController*) viewController).pageIndex;

  if (index == NSNotFound)
    return nil;

  index++;

  // If the current page is the last one then just start again (go in circle)
  if (index == [self.pageTitles count])
    index = 0;

  return [self viewControllerAtIndex:index];
}

I printed on my log the index values and it represents just that I was explained, i.e. index is 2 and after swipe is 4 (it should be 3) but in the device shows the third page with the third image but can't play the third video and only reproduce the sound of the fourth video. That isn't occurs when I tap on the page control indicator.

Edit

There are the rest of methods that I have in my PageViewcontroller

- (DemoTourViewController *)viewControllerAtIndex:(NSUInteger)index
{
  if (([self.pageTitles count] == 0) || (index >= [self.pageTitles count])) {
    return nil;
  }

  // Create a new view controller and pass suitable data.
  DemoTourViewController *pageContentVC = [self.storyboard instantiateViewControllerWithIdentifier:@"DemoTourViewController"];
  pageContentVC.imageFile = self.pageImages[index];
  pageContentVC.titleText = self.pageTitles[index];
  pageContentVC.pageIndex = index;
  pageContentVC.videoPath = [[NSBundle mainBundle]pathForResource:self.pageVideos[index] ofType:@"mp4"];
  pageContentVC.backgroundImgView.userInteractionEnabled = YES;

  return pageContentVC;
}

- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController
{
  return [self.pageTitles count]; 
}

- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController
{
  return 0;
}
1
There's nothing obviously wrong with that code - can you post some of your other code: the viewControllerAtIndex: method, and how pageTitles is populated. Thanks.pbasdf
Done, hope you can help me :) thank you @pbasdforigds
Can't see anything there either; the presentationIndex is obviously incorrect, but I think that's incidental to your problem.pbasdf
Thank you @pbasdf but I don't know how to fix it. I followed a tutorial for doing this and apparently I'm the one with this problemorigds
@pbasdf what should be the return of presentationIndexForPageViewController:pageViewController??origds

1 Answers

0
votes

Well, I thought about it overnight and I think your problem comes from starting the movie playing in the viewDidLoad method. It seems that when you use swipe gestures to switch pages, say from page 2 to page 3, the pageViewController not only loads and displays page 3, it also pre-emptively loads page 4. Presumably this is a performance optimisation, so if you swipe quickly again it has already loaded the next page. However, in your case this triggers the movie at index 4 to play (which you can hear, but not see, since that page has not yet been displayed). And because only one movie can be playing at a time, the movie on page 3 stops.

So, to fix it, I would change your code so that the movie only begins playing once the page is actually on screen. I think it will work OK if you move [self.player play] to the viewDidAppear: method. Happy to answer any questions via the chat session.