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

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

Я перешел по этой ссылке http://www.appcoda.com/uipageviewcontroller-tutorial-intro/.

Я выполняю простую задачу по изменению цвета фона моего "root 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;
}

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

С уважением Ранджит


person Ranjit    schedule 12.07.2013    source источник
comment
что именно вам нужно для управления страницей с помощью uiviews или uiviewcontrollers   -  person Vivek Sehrawat    schedule 12.07.2013
comment
@VivekSehrawat, функции делегата UIPageViewController работают только с VC. Так что я должен нам ВК   -  person Ranjit    schedule 12.07.2013
comment
Вы хотите изменить цвет фона APPChildViewController или APPViewController?   -  person Nguyen Thi Thuy Trang    schedule 12.07.2013
comment
@NguyenThiThuyTrang, измените цвет фона APPViewController   -  person Ranjit    schedule 12.07.2013
comment
@Ranjit: у меня есть ответ. и проверил это... вы можете попробовать это выше.   -  person Nguyen Thi Thuy Trang    schedule 12.07.2013
comment
@NguyenThiThuyTrang, я смотрю на это   -  person Ranjit    schedule 12.07.2013


Ответы (3)


Ведь много искал.

Я получаю это:

- (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];
}

Дайте мне знать, если у вас возникнут вопросы.

person Nguyen Thi Thuy Trang    schedule 12.07.2013
comment
функция делегата не вызывается - person Ranjit; 12.07.2013
comment
вы добавляете? : self.pageController.delegate = self; - person Nguyen Thi Thuy Trang; 12.07.2013
comment
эта функция доступна в Simulator 6.0 - person Nguyen Thi Thuy Trang; 12.07.2013
comment
pendingViewControllers - это NSMutableArray контроллеров представления? не могли бы вы добавить его код? - person androniennn; 18.07.2013
comment
@androniennn: да, pendingViewController - это NSMutableArray контроллера представления. и «не могли бы вы добавить его код?» что ты имеешь в виду? пожалуйста, объясните больше. - person Nguyen Thi Thuy Trang; 19.07.2013
comment
Спасибо за ответ, чувак, я уже сделал все необходимое :). Спасибо. - person androniennn; 19.07.2013
comment
Это решение, очевидно, сработало для вашего случая, но каков ответ на вопрос в строке темы? Почему метод вызывался дважды? Я сталкиваюсь с тем же самым сейчас в iOS7 и 8. - person James Paul Mason; 08.02.2015
comment
@NguyenThiThuyTrang мне все еще нужно использовать две функции? - person schinj; 04.01.2017

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

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

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

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

проверить изображение

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

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

person Gurunath Sripad    schedule 26.07.2017

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

- (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];

person Baby Groot    schedule 12.07.2013
comment
это не сработает, только если вы попытаетесь сменить страницу с контроллера страницы, а не жестом смахивания. - person Baby Groot; 12.07.2013