Подтвердить что ты не робот

Как добавить два контроллера представления в UIPageViewcontroller

Я использую UIPageViewController на iPad, где мне нужно показать firstviewController на первой странице и ContentViewController на следующей странице в альбомной ориентации.

Если я установил NSArray с двумя viewControllers, приложение выйдет из строя в [self.pagviewController setViewController:] со следующим исключением:

Количество предоставленных контроллеров представления (2) не соответствует требуемому числу (1) для запрашиваемого местоположения позвоночника (UIPageViewControllerSpineLocationMin)

Ниже приведен код:

#pragma mark - UIPageViewControllerDataSource Methods

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController 
      viewControllerBeforeViewController:(UIViewController *)viewController
{
    NSUInteger currentIndex = [self.modelArray indexOfObject:[(ContentViewController *)viewController textContents]];
    if(currentIndex == 0)
    {
        return nil;
    }
    ContentViewController *contentViewController = [[ContentViewController alloc] init];
    contentViewController.textContents = [self.modelArray objectAtIndex:currentIndex - 1];
    return contentViewController;
}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
       viewControllerAfterViewController:(UIViewController *)viewController
{
    NSUInteger currentIndex = [self.modelArray indexOfObject:[(ContentViewController *)viewController textContents]];
    if(currentIndex == self.modelArray.count-1)
    {
        return nil;
    }
    ContentViewController *contentViewController = [[ContentViewController alloc] init];
    contentViewController.textContents = [self.modelArray objectAtIndex:currentIndex + 1];

    return contentViewController;
}




//#pragma mark - UIPageViewControllerDelegate Methods

- (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController
                   spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
{
    if(UIInterfaceOrientationIsPortrait(orientation))
    {
        //Set the array with only 1 view controller
        UIViewController *currentViewController = [self.pageViewController.viewControllers objectAtIndex:0];
        NSArray *viewControllers = [NSArray arrayWithObject:currentViewController];

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

        //Important- Set the doubleSided property to NO.
        self.pageViewController.doubleSided = NO;
        //Return the spine location
        return UIPageViewControllerSpineLocationMin;
    }
    else
    {
        NSArray *viewControllers = nil;
        ContentViewController *currentViewController = [self.pageViewController.viewControllers objectAtIndex:0];

        NSUInteger currentIndex = [self.modelArray indexOfObject:[(ContentViewController *)currentViewController textContents]];
        if(currentIndex == 0 || currentIndex %2 == 0)
        {
            UIViewController *nextViewController = [self pageViewController:self.pageViewController viewControllerAfterViewController:currentViewController];
            viewControllers = [NSArray arrayWithObjects:currentViewController, nextViewController, nil];
        }
        else
        {
            UIViewController *previousViewController = [self pageViewController:self.pageViewController viewControllerBeforeViewController:currentViewController];
            viewControllers = [NSArray arrayWithObjects:previousViewController, currentViewController, nil];
        }
        //Now, set the viewControllers property of UIPageViewController
        [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];

        return UIPageViewControllerSpineLocationMid;
    }
}
- (void)viewDidLoad
{
    [super viewDidLoad];

    appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate];
    //Instantiate the model array
    self.modelArray = [[NSMutableArray alloc] init];
    self.vcs = [[NSMutableArray alloc]init];

    for (int index = 1; index <= 2 ; index++)
    {
        [self.modelArray addObject:[NSString stringWithFormat:@"Page %d",index]];
    }

    //Step 1
    //Instantiate the UIPageViewController.
    self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl
                                                              navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
    //Step 2:
    //Assign the delegate and datasource as self.
    self.pageViewController.delegate = self;
    self.pageViewController.dataSource = self;

    //Step 3:
    //Set the initial view controllers.

    appDelegate.contentViewController.textContents = [self.modelArray objectAtIndex:0];


    NSArray *viewControllers = [NSArray arrayWithObjects:appDelegate.firstViewController,appDelegate.contentViewController,nil];
    [self.pageViewController setViewControllers:viewControllers
                                      direction:UIPageViewControllerNavigationDirectionForward
                                       animated:NO
                                     completion:nil];

    //Step 4:
    //ViewController containment steps
    //Add the pageViewController as the childViewController
    [self addChildViewController:self.pageViewController];

    //Add the view of the pageViewController to the current view
    [self.view addSubview:self.pageViewController.view];

    //Call didMoveToParentViewController: of the childViewController, the UIPageViewController instance in our case.
    [self.pageViewController didMoveToParentViewController:self];

    //Step 5:
    // set the pageViewController frame as an inset rect.
    CGRect pageViewRect = self.view.bounds;
    pageViewRect = CGRectInset(pageViewRect, 40.0, 40.0);
    self.pageViewController.view.frame = pageViewRect;

    //Step 6:
    //Assign the gestureRecognizers property of our pageViewController to our view gestureRecognizers property.
    self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;
}
4b9b3361

Ответ 1

Проблема заключается в том, что вы передаете массив, содержащий два контроллера представления, в контроллер просмотра страниц, когда он ожидает по одному, измените свой массив следующим образом:

NSArray *viewControllers = @[appDelegate.firstViewController];

Вы пройдете одно из видов, но viewControllerAfterViewController и viewControllerBeforeViewController будут обрабатывать остальные.

Ответ 2

Ah..Наконец получил решение для этой же проблемы.., это может помочь вам.

Когда мы устанавливаем местоположение позвоночника на UIPageViewControllerSpineLocationMid, свойство doubleSided для pageViewController автоматически устанавливается на YES. Это означает, что содержимое на странице не будет отображаться частично назад. Но когда для этого свойства установлено значение НЕТ, содержимое на лицевой панели частично показывается через спину, придавая странице полупрозрачный вид эффекта. Итак, в портретной ориентации мы должны установить значение NO, иначе это приведет к исключению.

Итак, в вашем делегаторе UIPageviewcontroller, иначе добавьте это свойство doubleSided как ДА, когда вы вернете spineLocation как UIPageViewControllerSpineLocationMid

self.pageViewController.doubleSided = YES;
return UIPageViewControllerSpineLocationMid;

Ответ 3

self.pageViewController.doubleSided = NO;
return UIPageViewControllerSpineLocationMid;

Это решение для исключения.

В xcode вы можете найти это.

Перейдите в класс UIPageViewcontroller там, где вы можете увидеть объяснение для этого:

@property (nonatomic, readonly) UIPageViewControllerSpineLocation spineLocation; // If transition style is 'UIPageViewControllerTransitionStylePageCurl', default is 'UIPageViewControllerSpineLocationMin', otherwise 'UIPageViewControllerSpineLocationNone'.

// Whether client content appears on both sides of each page. If 'NO', content on page front will partially show through back.
// If 'UIPageViewControllerSpineLocationMid' is set, 'doubleSided' is set to 'YES'. Setting 'NO' when spine location is mid results in an exception.
@property (nonatomic, getter=isDoubleSided) BOOL doubleSided; // Default is 'NO'.

Ответ 4

Вместо того, чтобы внедрять полный источник данных, вы можете установить PageViewController с одним контроллером представления каждый раз, когда пользователь нажимает кнопку "Следующий" или "Назад", например

[pageViewController setViewControllers:@[contentViewController]
                             direction:UIPageViewControllerNavigationDirectionForward
                              animated:YES
                            completion:nil];

Это приведет к оживлению перехода страницы при переключении.