Функции делегата PageViewController называются дважды

Я работаю с UIPageViewController, чтобы совершить тур по продукту для моего приложения.

Я следил за этой ссылкой http://www.appcoda.com/uipageviewcontroller-tutorial-intro/

Я выполняю просто задачу изменения цвета backgound моего "корневого VC" при прокрутке на основе значения индекса, которое я получаю, но поскольку функции делегата вызываются дважды, мое значение индекса равно Неправильно, и из-за этого я не могу понять это, ниже мой код

#import "APPViewController.h"
#import "APPChildViewController.h"

@interface APPViewController ()

@end

@implementation APPViewController

- (void)viewDidLoad {

    [super viewDidLoad];

    self.pageController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];

    self.pageController.dataSource = self;
    [[self.pageController view] setFrame:CGRectMake(0, 0, 320, 500)];

    APPChildViewController *initialViewController = [self viewControllerAtIndex:0];

    NSArray *viewControllers = [NSArray arrayWithObject:initialViewController];

    [self.pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];

    [self addChildViewController:self.pageController];
    [[self view] addSubview:[self.pageController view]];
    [self.pageController didMoveToParentViewController:self];

}

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.

}

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

    APPChildViewController *childViewController = [[APPChildViewController alloc] initWithNibName:@"APPChildViewController" bundle:nil];
    childViewController.index = index;
    childViewController.view.backgroundColor = [UIColor clearColor];

    if(index == 0)
    {
          self.view.backgroundColor = [UIColor redColor];
     }

    if(index == 1)
    {
          self.view.backgroundColor = [UIColor blueColor];
     }

    if(index == 2)
    {
          self.view.backgroundColor = [UIColor greenColor];
     }


    return childViewController;

}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {

    NSUInteger index = [(APPChildViewController *)viewController index];

    if (index == 0) {
        return nil;
    }

    // Decrease the index by 1 to return
    index--;

   return [self viewControllerAtIndex:index];

}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {

    NSUInteger index = [(APPChildViewController *)viewController index];

    index++;

    if (index == 3) {
        return nil;
    }

   return [self viewControllerAtIndex:index];

}

- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController {
    // The number of items reflected in the page indicator.
    return 3;
}

- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController {
    // The selected item reflected in the page indicator.
    return 0;
}

Пожалуйста, помогите мне, я не понимаю, где я ошибаюсь

Отношения Ранджит

Ответ 1

После долгого поиска.

Получаю, что:

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController;
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController;

2 функции используются для получения pageViewController позади или перед текущим pageViewController.

Мне кажется, что трудно получить текущий pageViewController

Мое предложение:

В UIPageViewControllerDelegate у него есть функция:

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

Эта функция дает вам массив pendingViewControllers и этот текущий массив pageViewController. Таким образом, вы можете реализовать это:

- (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers
{


if([pendingViewControllers count]>0)
  {
     NSUInteger index =[(APPChildViewController*)[pendingViewControllers objectAtIndex:0] index];

    if(index == 0)
    {
        self.view.backgroundColor = [UIColor redColor];
    }

    if(index == 1)
    {
        self.view.backgroundColor = [UIColor blueColor];
    }

    if(index == 2)
    {
        self.view.backgroundColor = [UIColor greenColor];
    }


  }
}

В viewDidLoad вы добавляете:

    self.pageController.delegate = self;

    self.view.backgroundColor = [UIColor redColor]; //set first background.

В "APPViewController.h" вы обязательно добавите:

@interface APPViewController : UIViewController<UIPageViewControllerDataSource,UIPageViewControllerDelegate>

Помните: удалите этот код (в функции viewControllerAtIndex)

if(index == 1)
{
    self.view.backgroundColor = [UIColor redColor];
}

if(index == 2)
{
    self.view.backgroundColor = [UIColor blueColor];
}

if(index == 3)
{
    self.view.backgroundColor = [UIColor greenColor];
}

Сообщите мне, если у вас есть какие-либо вопросы.

Ответ 2

Замените эти два метода и скомпилируйте,

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {

    NSUInteger index = [(APPChildViewController *)viewController index];
    if (index == 0)
    {
        self. view.backgroundColor = [UIColor redColor];
        return nil;
    }

    if(index == 1)
    {
        self.view.backgroundColor = [UIColor blueColor];
    }

    if(index == 2)
    {
        self.view.backgroundColor = [UIColor greenColor];
    }
    if(index == 3)
    {
        self.view.backgroundColor = [UIColor brownColor];
    }
    /*if(index == 4)
    {
        self.view.backgroundColor = [UIColor whiteColor];
    }*/

    // Decrease the index by 1 to return
    index--;

    return [self viewControllerAtIndex:index];

}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {

    NSUInteger index = [(APPChildViewController *)viewController index];
    /*if(index == 0)
    {
        self.view.backgroundColor = [UIColor redColor];
    }*/
    if(index == 1)
    {
        self.view.backgroundColor = [UIColor blueColor];
    }

    if(index == 2)
    {
        self.view.backgroundColor = [UIColor greenColor];
    }
    if(index == 3)
    {
        self.view.backgroundColor = [UIColor brownColor];
    }
    if(index == 4)
    {
        self.view.backgroundColor = [UIColor whiteColor];
        return nil;
    }

    /*if (index == 5) {
        return nil;
    }*/
    index++;

    return [self viewControllerAtIndex:index];

}

и добавьте это в конец - (void)viewDidLoad {

self.view.backgroundColor = [UIColor redColor];

Ответ 3

Я столкнулся с той же проблемой и, наконец, понял причину. Методы делегата вызываются дважды, когда для стиля перехода для контроллера просмотра страницы установлено значение "Curl Page".

Когда для стиля перехода установлено значение "Page Curl", действие похоже на поворот страницы в книге. Вы поворачиваете одну страницу, а номер страницы увеличивается на 2. Применяя одну и ту же концепцию для контроллера просмотра страниц, 2 вида контроллеров переходят в стиль страницы Curl: один из них - контроллер вида, который вы видите, а другой контроллер просмотра находится с другой стороны скрученного вида.

Измените стиль перехода на "Прокрутка", и вы можете избавиться от проблемы.

Это можно сделать из раскадровки в инспекторе атрибутов следующим образом: проверить изображение

Вы также можете изменить его код, установив для свойства UIPageViewController.transitionStyle значение UIPageViewControllerTransitionStyleScroll.

Надеюсь, что это поможет