如何在UIPageViewcontroller中添加两个视图控制器

时间:2013-04-04 09:14:28

标签: ios objective-c uipageviewcontroller

我在iPad上使用UIPageViewController,我需要在第一页显示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's 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's gestureRecognizers property.
    self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;
}

4 个答案:

答案 0 :(得分:22)

问题是您将包含两个视图控制器的数组传递给页面视图控制器,而它一次只需要一个,将数组更改为:

NSArray *viewControllers = @[appDelegate.firstViewController];

您将传递其中一个视图,但viewControllerAfterViewControllerviewControllerBeforeViewController将处理其余视图。

答案 1 :(得分:1)

啊......最终得到了同样问题的解决方案......,它可能对你有帮助..

当我们将脊椎位置设置为UIPageViewControllerSpineLocationMid时,pageViewController的doubleSided属性会自动设置为YES。这意味着页面前面的内容不会部分显示回来。但是当此属性设置为NO时,页面前面的内容将部分显示回来,使页面具有半透明效果。因此,在纵向方向上,我们必须将值设置为NO,否则会导致异常。

因此,在UIPageviewcontroller委托方法中,在其他部分中,当您将spineLocation作为doubleSided

返回时,将此UIPageViewControllerSpineLocationMid属性添加为YES
self.pageViewController.doubleSided = YES;
return UIPageViewControllerSpineLocationMid;

答案 2 :(得分:0)

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'.

答案 3 :(得分:-2)

每次用户按下一个或后一个按钮时,您可以一次设置一个视图控制器,而不是实现完整的数据源,例如

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

这将在您切换时为页面转换设置动画。