我一直在研究一個簡單的測試應用程序,以瞭解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