我一直在研究一个简单的测试应用程序,以了解UIPageViewController的来龙去脉。我有它的工作,但我不相信我的执行是最好的方式。我希望你们中的一些人能够指引我正确的方向。如何实现使用多个ViewControllers的UIPageViewController
为了获得基本的理解,我以本教程为出发点。 http://www.appcoda.com/uipageviewcontroller-storyboard-tutorial/
本教程将创建一个应用程序,该应用程序对UIPageViewController
提供的每个页面使用一个viewController
。不过,我需要利用UIPageViewController滚动具有完全不同布局的页面。因此,为了让本教程更进一步,我创建了一个主详图应用程序,它在详细视图中使用UIPageViewController来显示三个不同的视图控制器。我坚持只显示这个测试应用程序的图像和标签,但我目前正在构建的应用程序有三个viewController,它们将包含tableview,imageView和textViews,或一些textFields。
这是我的测试应用程序的故事板。
我使用DetailViewController
作为PageViewController
的数据源。在DVC的viewDidLoad
中,我以这种方式建立将在三个内容视图控制器firstViewController
,secondViewController
和thirdViewController
中使用的标签和图像。
if ([[self.detailItem description] isEqualToString:@"F14's"]) {
//Here the page titles and images arrays are created
_pageTitles = @[@"Grim Reapers", @"Breakin the Barrier!", @"Top Gun"];
_pageImages = @[@"F14_Grim.jpg", @"F14boom.jpg", @"F14_topgun.jpg"];
//Here I call a method to instantiate the viewControllers
FirstController *selectedController = [self viewControllerAtIndex:0];
SecondController *nextController = [self viewControllerAtIndex:1];
ThirdController *lastController = [self viewControllerAtIndex:2];
[_vc addObject:selectedController];
[_vc addObject:nextController];
[_vc addObject:lastController];
_vc1 = @[selectedController];
} else if ([[self.detailItem description] isEqualToString:@"F35's"]){
//code is above is repeated
下面是实例化viewControllers
- (UIViewController *)viewControllerAtIndex:(NSUInteger)index
{
if (([self.pageTitles count] == 0) || (index >= [self.pageTitles count])) {
return nil;
}
// Create a new view controller and pass suitable data.
if (index == 0) {
FirstController *fvc = [self.storyboard instantiateViewControllerWithIdentifier:@"FirstPageController"];
fvc.imageFile = self.pageImages[index];
fvc.titleText = self.pageTitles[index];
fvc.pageIndex = index;
if ([_vc count]) {
//Here I have to replace the viewController each time it is recreated
[_vc replaceObjectAtIndex:0 withObject:fvc];
}
return fvc;
} else if (index == 1) {
//Code is repeated for remaining viewControllers
在viewDidLoad
的代码是一个领域,我觉得我做unnecassary工作方法。我不相信我需要在加载DVC时实例化所有三个视图控制器,但我不知道如何为UIPageViewControllerDataSource协议方法(viewControllerBeforeViewController
和viewControllerAfterViewController
)提供数组。
这里是方法。
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
NSUInteger index = [_vc indexOfObject:viewController];
if ((index == 0) || (index == NSNotFound)) {
return nil;
}
index--;
//notice here I call my instantiation method again essentially duplicating work I have already done!
return [self viewControllerAtIndex:index];
}
总之,似乎我unnecassarily与从一个网页到另一个每次刷卡重新创建视图控制器。这仅仅是pageViewController的工作原理,或者让我的方式过程复杂化。任何输入都会很棒!
SOLUTION
马特使用标识符建议了一种非常简单的解决方案。在我的故事板,我只是检查了使用我已经实现故事板标识符作为恢复标识符
然后在viewDidLoad
而不是创造viewControllers阵列盒,只需创建与恢复标识符字符串数组。
if ([[self.detailItem description] isEqualToString:@"F14's"]) {
_pageTitles = @[@"Grim Reapers", @"Breakin the Barrier!", @"Top Gun"];
_pageImages = @[@"F14_Grim.jpg", @"F14boom.jpg", @"F14_topgun.jpg"];
FirstController *selectedController = [self viewControllerAtIndex:0];
[_vc addObject:@"FirstPageController"];
[_vc addObject:@"SecondPageController"];
[_vc addObject:@"ThirdPageController"];
_vc1 = @[selectedController];
最后确定委托方法的指数做到这一点,而不是之前,我在做什么:
NSString * ident = viewController.restorationIdentifier;
NSUInteger index = [_vc indexOfObject:ident];
现在的工作,而无需不必要的实例化视图控制器。
作为最后一个音符,如果有人正在使用的正是我在这里,你可以摆脱从viewControllerAtIndex:
方法下面的代码片断的。
if ([_vc count]) {
//Here I have to replace the viewController each time it is recreated
[_vc replaceObjectAtIndex:0 withObject:fvc];
}
你能上传一些关于这个例子的代码吗?谢谢! – fguespe
@fguespe你应该有这里所需的一切来解决这个问题......不知道你在找什么......注意我在我的问题的底部添加了一个解决方案 – Ben
这是一个很棒的解决方案。但是我无法获得用于其他功能的正确页面索引。您是否将NSString * ident等放入根控制器或模型的 - (NSUInteger)indexOfViewController:(embBaseViewController *)viewController中? – malaki1974