基於分頁導航實現ios
在iOS 5以後,可使用分頁控制器(UIPageViewController)構建相似於電子書效果的應用,咱們稱爲基於分頁的應用。一個分頁應用有不少相關的視圖控制器ide
分頁控制器(PageViewController)須要放置在一個父視圖控制器中,在分頁控制器下面還要有子視圖控制器,每一個子視圖控制器對應圖中的一個頁面。atom
在基於分頁導航實現的應用中須要的類和協議:UIPageViewControllerDataSource協議和 UIPageViewControllerDelegate協議和UIPageViewController 類,UIPageViewController沒有對應的視圖類。url
UIPageViewControllerDelegate委託協議中,最重要的方法爲 pageViewController:spineLocationForInterfaceOrientation:,它根據屏幕旋轉方向設置書脊位置 (Spine Location)和初始化首頁。spa
UIPageViewController中有兩個經常使用的屬性:雙面顯示(doubleSided)和書脊位置(spineLocation)。設計
1.雙面顯示,是在頁面翻起的時候,偶數頁面會在背面顯示。圖爲doubleSided設置爲YES狀況,圖6-14中圖爲 doubleSided設置爲NO(單面顯示),單面顯示在頁面翻起的時候,可以看到頁面的背面,背面的內容是當前頁面透過去的,與當前內容是相反的鏡 像。orm
2.書脊位置。書脊位置也是很重要的屬性,可是它的spineLocation 屬性是隻讀的,要設置它,須要經過 UIPageViewControllerDelegate委託協議中的 pageViewController:spineLocationForInterfaceOrientation:方法。書脊位置由枚舉 UIPageViewControllerSpineLocation定義,該枚舉類型下的成員變量以下所示。索引
下面咱們使用頁面導航實現城市信息這個應用。使用Single View Application模板建立一個名爲 PageNavigation的工程。get
能夠從PageControlNavigation工程中複製過來,方法是在打開MainStoryboard.storyboard選中3個視圖 控制器,按下Command+C組合鍵拷貝,再到PageNavigation中打開MainStoryboard.storyboard,按下 Command+V組合鍵粘貼,就能夠了。string
這樣UI設計工做就結束了,下面的工做都是由代碼完成的。咱們先看看ViewController.h的代碼:
- #import <UIKit/UIKit.h>
- @interface ViewController : UIViewController <UIPageViewControllerDataSource,UIPageViewControllerDelegate>
- {
- //當前頁面的索引
- int pageIndex;
- }
- @property (strong, nonatomic) UIPageViewController *pageViewController;
- @end
在上述代碼中,ViewController實現了UIPageViewControllerDataSource和 UIPageViewControllerDelegate協議。成員變量pageIndex保存了當前頁面的索 引,pageViewController屬性保存了UIPageViewController實例。
下面咱們看看程序代碼ViewController.m的viewDidLoad方法:
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- self.view.frame = CGRectMake(0.0f, 0.0f, 320.0f, 440.0f);
- self.pageViewController = [[UIPageViewController alloc]
- initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl
- navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
- self.pageViewController.delegate = self;
- self.pageViewController.dataSource = self;
- UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
- UIViewController* page1ViewController = [mainStoryboard instantiateViewControllerWithIdentifier:@"page1"];
- //第一個視圖,最爲PageViewController首頁
- NSArray *viewControllers = @[page1ViewController];
- [self.pageViewController setViewControllers:viewControllers
- direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
- [self addChildViewController:self.pageViewController];
- [self.view addSubview:self.pageViewController.view];
- pageIndex = 0;
- }
在上述代碼中,initWithTransitionStyle:navigationOrientation:options:構造方法用於建立 UIPageViewController實例,initWithTransitionStyle用於設定頁面翻轉的樣式。 UIPageViewControllerTransitionStyle枚舉類型定義了以下兩個翻轉樣式。
UIPageViewControllerTransitionStylePageCurl:翻書效果樣式。
UIPageViewControllerTransitionStyleScroll:滑屏效果樣式。
navigationOrientation設定了翻頁方向,UIPageViewControllerNavigationDirection枚舉類型定義瞭如下兩種翻頁方式。
UIPageViewControllerNavigationDirectionForward:從左往右(或從下往上);
UIPageViewControllerNavigationDirectionReverse:從右向左(或從上往下)。
代碼NSArray *viewControllers = @[page1ViewController]至關於NSArray *viewControllers = [NSArray arrayWithObject: page1ViewController , nil]。
在UIPageViewController 中,setViewControllers:direction:animated:completion:方法用於設定首頁中顯示的視圖。首頁中顯示幾 個視圖與書脊類型有關,若是是UIPageViewControllerSpineLocationMin或 UIPageViewControllerSpineLocationMax,首頁中顯示一個視圖;若是是 UIPageViewControllerSpineLocationMid,首頁中顯示兩個視圖。
[self addChildViewController:self.pageViewController]語句是將PageViewController添加到父視圖控制器中去。
咱們再看看ViewController.m中有關數據源UIPageViewControllerDataSource協議實現方法的代碼:
- - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
- viewControllerBeforeViewController:(UIViewController *)viewController
- {
- pageIndex–;
- if (pageIndex < 0){
- pageIndex = 0;
- return nil;
- }
- UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
- NSString *pageId = [NSString stringWithFormat:@"page%i",pageIndex+1];
- UIViewController* pvController = [mainStoryboard instantiateViewControllerWithIdentifier:pageId];
- return pvController;
- }
- - (UIViewController *)pageViewController:(UIPageViewController *)pageViewController
- viewControllerAfterViewController:(UIViewController *)viewController
- {
- pageIndex++;
- if (pageIndex > 2){
- pageIndex = 2;
- return nil;
- }
- UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
- NSString *pageId = [NSString stringWithFormat:@"page%i",pageIndex+1];
- UIViewController* pvController = [mainStoryboard instantiateViewControllerWithIdentifier:pageId];
- return pvController;
- }
- 在ViewController.m中,有關委託協議UIPageViewControllerDelegate實現方法的代碼以下:
- - (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController
- spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
- {
- self.pageViewController.doubleSided = NO;
- return UIPageViewControllerSpineLocationMin;
- }
- 因爲spineLocation屬性是隻讀的,因此只能在這個方法中設置書脊位置,該方法能夠根據屏幕旋轉方向的不一樣來動態設定書脊的位置,實現代碼能夠參考下面的代碼:
- - (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController
- spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation
- {
- UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
- UIViewController* page1ViewController = [mainStoryboard instantiateViewControllerWithIdentifier:@"page1"];
- UIViewController* page2ViewController = [mainStoryboard instantiateViewControllerWithIdentifier:@"page2"];
- if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight)
- {
- //取出第一個視圖控制器,最爲PageViewController首頁
- NSArray *viewControllers = @[page1ViewController, page2ViewController];
- [self.pageViewController setViewControllers:viewControllers
- direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
- self.pageViewController.doubleSided = NO;
- return UIPageViewControllerSpineLocationMid;
- }
- //取出第一個視圖控制器,最爲PageViewController首頁
- NSArray *viewControllers = @[page1ViewController];
- [self.pageViewController setViewControllers:viewControllers
- direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL];
- self.pageViewController.doubleSided = NO;
- return UIPageViewControllerSpineLocationMin;
- }
這只是一個基本的實現,要根據具體的應用具體再定。用平鋪導航實現時,UIPageViewController每每不須要實現屏幕旋轉的支持,並且書脊的位置也不會設置在中間。
代碼編寫完畢看效果。