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
how to add two view controllers in UIPageViewcontroller
提问by user578386
I m using UIPageViewController
on iPad where I need to show a firstviewController
in the first page and ContentViewController
in the next page in landscape.
我UIPageViewController
在 iPad 上使用,我需要firstviewController
在第一页和ContentViewController
下一页中显示横向。
If I set the NSArray
with two viewControllers
the 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 viewControllerAfterViewController
and viewControllerBeforeViewController
will handle the rest.
你会通过的意见之一,但viewControllerAfterViewController
和viewControllerBeforeViewController
将处理其余部分。
回答by wesley
Ah..Finally got solution for this same issue.., it may helps you..
啊..终于得到了同样问题的解决方案..,它可能会帮助你..
When we set the spine location to UIPageViewControllerSpineLocationMid
, the doubleSided
property 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.
当我们将脊椎位置设置为 时UIPageViewControllerSpineLocationMid
,doubleSided
pageViewController的属性会自动设置为 YES。这意味着页面前面的内容不会部分显示在后面。但是当这个属性设置为NO时,页面前面的内容会部分透出,给页面一种半透明的效果。所以,在纵向时,我们必须将该值设置为NO,否则会导致异常。
So in your UIPageviewcontroller
delegate method, in else part add this doubleSided
property 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 UIPageViewcontroller
class 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.
这将在您切换时为页面过渡设置动画。