如何在UIPageViewcontroller中添加两个视图控制器
我在iPad上使用UIPageViewController
,我需要在第一页显示firstviewController
,在横向显示下一页显示ContentViewController
。如何在UIPageViewcontroller中添加两个视图控制器
如果我设置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;
}
无需实现完整的数据源,则可以在一个时间每个用户按下下一个或后退按钮时设置与一个视图控制器PageViewController,像
[pageViewController setViewControllers:@[contentViewController]
direction:UIPageViewControllerNavigationDirectionForward
animated:YES
completion:nil];
此作为切换将动画页面转换。
Ah..Finally得到了同样的问题解决方案..,它可以帮助你..
当我们设定的脊柱位置UIPageViewControllerSpineLocationMid
,在pageViewController的doubleSided
属性被自动设置为YES。这意味着页面上的内容不会部分显示在后面。但是,当此属性设置为NO时,页面上的内容将部分显示在后面,从而使页面具有半透明效果。因此,在纵向方向上,我们必须将值设置为NO,否则会导致异常。
UIPageviewcontroller
委托方法
因此,在其他部分本doubleSided
属性添加的是,当您返回spineLocation为UIPageViewControllerSpineLocationMid
self.pageViewController.doubleSided = YES;
return UIPageViewControllerSpineLocationMid;
问题是你传递包含两个视图控制器到页面视图控制器,而阵列它预计,一次一个,改变你的阵列是这样的:
NSArray *viewControllers = @[appDelegate.firstViewController];
你会通过的意见之一,但viewControllerAfterViewController
和viewControllerBeforeViewController
将处理其余的。
为什么这个调用的参数是一个数组,如果它只需要一个视图控制器? – Shoerob 2015-09-01 03:01:32
@Shoerob根据文档'对于过渡样式'UIPageViewControllerTransitionStylePageCurl',如果'doubleSided'是'YES'且主干位置不是'UIPageViewControllerSpineLocationMid',则必须包含两个视图控制器,因为后一个视图控制器被用作背面.' – 2015-11-18 10:59:35
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'.
你需要通过你的数据源提供一次在一个页面,如果你只是想显示一个页面,这就是为什么你的应用程序崩溃 - 它有两个页面显示当它期待一个(当我在纵向模式)。向我们显示您的委托和数据源代码。 – 2013-04-04 09:31:38
确实花花公子.......但应用程序在视图中压缩DadLoad – user578386 2013-04-04 09:37:06
检查上面的代码 – user578386 2013-04-04 09:39:37