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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15807040/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 23:01:41  来源:igfitidea点击:

how to add two view controllers in UIPageViewcontroller

iosobjective-cuipageviewcontroller

提问by user578386

I m using UIPageViewControlleron iPad where I need to show a firstviewControllerin the first page and ContentViewControllerin the next page in landscape.

UIPageViewController在 iPad 上使用,我需要firstviewController在第一页和ContentViewController下一页中显示横向。

If I set the NSArraywith two viewControllersthe app is crashes at [self.pagviewController setViewController:]with the following exception:

如果我将NSArray两个设置为viewControllers应用程序崩溃,[self.pagviewController setViewController:]但出现以下异常:

The number of provided view controllers (2) doesn't match the number required (1) for the requested spine location (UIPageViewControllerSpineLocationMin)

提供的视图控制器的数量 (2) 与请求的脊椎位置 (UIPageViewControllerSpineLocationMin) 所需的数量 (1) 不匹配

Below is the code:

下面是代码:

#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;
}

回答by Ben

The problem is you passing an array containing two view controllers to the page view controller while it expects one at a time, change your array to be like this :

问题是您将包含两个视图控制器的数组传递给页面视图控制器,而它期望一次一个,将数组更改为如下所示:

NSArray *viewControllers = @[appDelegate.firstViewController];

You will pass one of the views but viewControllerAfterViewControllerand viewControllerBeforeViewControllerwill handle the rest.

你会通过的意见之一,但viewControllerAfterViewControllerviewControllerBeforeViewController将处理其余部分。

回答by wesley

Ah..Finally got solution for this same issue.., it may helps you..

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

When we set the spine location to UIPageViewControllerSpineLocationMid, the doubleSidedproperty of the pageViewController is automatically set to YES. This means that the content on page front will not partially show through back. But when this property is set to NO, the content on page front will partially show through back, giving the page a translucent kind of effect. So, in the portrait orientation, we have to set the value to NO, otherwise it would result in an exception.

当我们将脊椎位置设置为 时UIPageViewControllerSpineLocationMiddoubleSidedpageViewController的属性会自动设置为 YES。这意味着页面前面的内容不会部分显示在后面。但是当这个属性设置为NO时,页面前面的内容会部分透出,给页面一种半透明的效果。所以,在纵向时,我们必须将该值设置为NO,否则会导致异常。

So in your UIPageviewcontrollerdelegate method, in else part add this doubleSidedproperty as YES when you return spineLocation as UIPageViewControllerSpineLocationMid

所以在你的UIPageviewcontroller委托方法中,doubleSided当你返回spineLocation作为时,在其他部分添加这个属性为YESUIPageViewControllerSpineLocationMid

self.pageViewController.doubleSided = YES;
return UIPageViewControllerSpineLocationMid;

回答by Mini

self.pageViewController.doubleSided = NO;
return UIPageViewControllerSpineLocationMid;

This is the solution for the exception.

这是异常的解决方案。

In xcode it self you could find this.

在 xcode it self 你可以找到这个。

Go to the UIPageViewcontrollerclass there you could see the explanation for this like:

转到那里的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'.

回答by Dominator1113

Instead of implementing a full data source, you can set the PageViewController with one view controller at a time each time the user pushes a next or back button, like

无需实现完整的数据源,您可以在每次用户按下下一步或后退按钮时使用一个视图控制器设置 PageViewController,例如

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

This will animate the page transition as you switch.

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