iOS 5 :一個UIPageViewController程式樣本

來源:互聯網
上載者:User

原文:http://www.techotopia.com/index.php/An_Example_iOS_5_iPhone_UIPageViewController_Application

在Xcode中建立項目時,可以選擇“Page-based Application”項目模板。可以利用這個模板建立一種“基於頁”的應用程式,在1年的每個月中顯示不同的頁。奇怪的是,這是Xcode提供的唯一一個基於執行個體的模板而不是應用程式基底本架構。這對於一開始學習時很有用,但除非你真的需要一個用12頁來顯示1年不同月份的程式,否則你必需從這個模板中移除一些已有的東西,以用於其他目的。

實際上,除了使用Xcode’s的“Page-based Application”模板,我們也可以使用Single View Application 模板,只不過自己需要實現Page-based的行為。這有兩方面的好處。首先,不使用Page-base模板能使我們更能理解UIPageViewController的實現細節。其次,這種方式也比去修改Page-based Application模板要更加簡捷。

建立項目

啟動Xcode,建立iOS single view application項目,確認不要使用Use Storyboard選項。

建立contentViewController

本樣本使用單個View Controller執行個體顯示多個頁。視圖中包含了一個UIWebView,根據當前選擇的頁顯示不同Html內容。ViewController類有一個data對象屬性用於持有視圖的Html。

選擇FileàNewàNewFile…菜單,建立UIViewController subclass,名為contentViewController(勾選“With XIB…”選項)。開啟contentViewController.h,為webview對象和data對象添加出口並進行串連。

#import <UIKit/UIKit.h>
@interface contentViewController : UIViewController 
@property (strong, nonatomic) IBOutlet UIWebView *webView; 
@property (strong, nonatomic) id dataObject; 
@end 

然後,開啟contentViewController.xib,拖一個UIWebView組件到view上:

右鍵從File’s Owner 拖一條連接線到web view對象並選擇webView出口。

編輯contentViewController.m檔案。每當使用者翻頁時,UIPageViewController的資料來源方法會建立一個新的contentViewController執行個體然後設定其dataObject屬性為相應的Html。而在contentViewController的viewWillAppear方法中,我們會將dataObject屬性賦給webview對象。為此,我們加入了必要的@synthesize語句,同時修改了viewWillAppear方法:

#import "contentViewController.h"  
@implementation contentViewController 
@synthesize webView, dataObject; 
. 
. 
- (void)viewWillAppear:(BOOL)animated {
     [super viewWillAppear:animated];
     [webView loadHTMLString:dataObject
         baseURL:[NSURL URLWithString:@""]]; 
} 
. 
. 
@end 

接下來,我們來實現資料模型。

建立資料模型

本例中的資料模型是一個字串數組。每個字串是內容不同的Html內容。pageAppViewController類就是UIPageViewController對象的資料來源。該類含有一個NSArry和一個UIPageViewController對象,同時實現UIPageViewcontrollerDataSource協議。開啟pageAppViewController.h,匯入contentViewController.h標頭檔,加入必要的聲明:

 

#import <UIKit/UIKit.h> 
#import “contentViewController.h”  
@interface pageAppViewController : UIViewController <UIPageViewControllerDataSource> {
     UIPageViewController *pageController;
     NSArray *pageContent; 
} 
@property (strong, nonatomic) UIPageViewController *pageController; 
@property (strong, nonatomic) NSArray *pageContent; 
@end 

最後,在pageAppViewController.m中增加一個方法以把Html字串加到數組中。然後在viewDidLoad方法中調用這個方法。

 
#import "pageAppViewController.h"  
@implementation pageAppViewController 
@synthesize pageController, pageContent;
 .
 . 
- (void) createContentPages {
     NSMutableArray *pageStrings = [[NSMutableArray alloc] init];
     for (int i = 1; i < 11; i++)
     {
         NSString *contentString = [[NSString alloc]
 initWithFormat:@"<html><head></head><body><h1>Chapter %d</h1><p>This is the page %d of content displayed using UIPageViewController in iOS 5.</p></body></html>", i, i];
         [pageStrings addObject:contentString];
     }
     pageContent = [[NSArray alloc] initWithArray:pageStrings]; 
}
 .
 . 
- (void)viewDidLoad {
     [super viewDidLoad];
     [self createContentPages]; 
} 
 

現在,我們已經有一個content view controller和一個data model了,data model將通過資料來源方法來提取每一頁的內容。下一步,就是實現這些資料來源方法。如“Implementinga Page based iOS 5 iPhone Application using UIPageViewController”中所述, UIPageViewController 執行個體需要一個資料來源,資料來源方法有兩個,一個是返回當前顯示的view controller之後的view controller,而另一個是返回當前顯示的view controller之前的viewcontroller。由於pageAppViewController扮演了page view controller的資料來源,因此需要在pageAppViewController.m中加入這兩個方法(以及另外兩個便利方法)。首先我們來看這2個便利方法:

 

#import "pageAppViewController.h"  
@implementation pageAppViewController 
@synthesize pageController, pageContent;  
- (contentViewController *)viewControllerAtIndex:(NSUInteger)index {
     // Return the data view controller for the given index.
     if (([self.pageContent count] == 0) || 
             (index >= [self.pageContent count])) {
         return nil;
     }
      // Create a new view controller and pass suitable data.
     contentViewController *dataViewController = 
         [[contentViewController alloc]
         initWithNibName:@"contentViewController" 
         bundle:nil];
     dataViewController.dataObject =
        [self.pageContent objectAtIndex:index];
     return dataViewController; 
- (NSUInteger)indexOfViewController:(contentViewController *)viewController {
      return [self.pageContent 
indexOfObject:viewController.dataObject]; 
}
 .
 . 
@end 

 

viewControllerAtIndex: 方法首先檢查有效頁數是否<0(使用者不可能回到第1頁以前)或者要檢索的頁數已經超出了pageContent數組的實際數目。如果index參數有效,就建立一個新的contentViewController執行個體並將dataObject屬性設定為相應的pageContent條目(Html字串)。

 indexOfViewController 方法指定一個viewController作為參數,並返回這個viewController的索引。它使用viewcontroller的dataObject屬性去在pageContent數組元素中檢索其索引

現在來看兩個資料來源方法。它們使用這兩個便利方法返回當前view  controller“之前”和“之後”的view  controller:

 
- (UIViewController *)pageViewController: (UIPageViewController *)pageViewController viewControllerBeforeViewController: (UIViewController *)viewController {
     NSUInteger index = [self indexOfViewController:
        (contentViewController *)viewController];
     if ((index == 0) || (index == NSNotFound)) {
         return nil;
     }
      index--;
     return [self viewControllerAtIndex:index]; 
- (UIViewController *)pageViewController: (UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {
     NSUInteger index = [self indexOfViewController:
         (contentViewController *)viewController];
     if (index == NSNotFound) {
         return nil;
     }
      index++;
     if (index == [self.pageContent count]) {
         return nil;
     }
     return [self viewControllerAtIndex:index]; 
}
 

下一步,就是建立和執行個體化UIPageViewController類。

 執行個體化UIPageViewController

接下來就是建立UIPageViewController執行個體並初始化。用於這個過程只需要進行一次,因此把代碼寫在pageAppViewController的viewDidLoad方法中就可以了。開啟pageAppViewController.m 檔案修改 viewDidLoad:

 

- (void)viewDidLoad {
     [super viewDidLoad];
     [self createContentPages];
     NSDictionary *options =
       [NSDictionary dictionaryWithObject:
      [NSNumber
 numberWithInteger:UIPageViewControllerSpineLocationMin]
      forKey: UIPageViewControllerOptionSpineLocationKey];
      self.pageController = [[UIPageViewController alloc]         initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl   navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal
        options: options];
      pageController.dataSource = self;
     [[pageController view] setFrame:[[self view] bounds]];
      contentViewController *initialViewController =
         [self viewControllerAtIndex:0];
     NSArray *viewControllers =
          [NSArray arrayWithObject:initialViewController];     
     [pageController setViewControllers:viewControllers
         direction:UIPageViewControllerNavigationDirectionForward
        animated:NO
        completion:nil];
      [self addChildViewController:pageController];
     [[self view] addSubview:[pageController view]];
     [pageController didMoveToParentViewController:self]; 
} 

 

全部代碼到此結束。在編譯和運行程式之前,我們先分析一下viewDidLoad方法中的代碼。

構建資料模型之後,我們建立了一個NSDictionary對象。這個NSDictionary中包含了一個options,用於page controrller對象的初始化選項。在這裡,該選項指定了spine位於螢幕左側(spine即書脊,書頁裝訂的位置,書從另一側翻閱):

 

NSDictionary *options =     [NSDictionary dictionaryWithObject:     [NSNumber numberWithInteger:UIPageViewControllerSpineLocationMin]     forKey: UIPageViewControllerOptionSpineLocationKey]; 
 

下一句,用前面的options執行個體化UIPageViewController:

 
self.pageController = [[UIPageViewController alloc]    initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl   navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal   options: options]; 
 
要讓類成為page controller的資料來源,還要做一些配置。比如我們要讓頁面全屏,需要設定它的frame:
 
pageController.dataSource = self; 
[[pageController view] setFrame:[[self view] bounds]]; 
 
 

在第1頁能顯示之前,我們首先需要建立一個view controller。這可以調用 viewControllerAtIndex: 便利方法。 在獲得一個contentview controller後,把它放到一個數組對象中:

 
contentViewController *initialViewController =
     [self viewControllerAtIndex:0]; 
NSArray *viewControllers =
      [NSArray arrayWithObject:initialViewController]; 

 

注意,只需要一個content view controller。因為page controller被設定為一次只顯示1頁(單面)。如果將pagecontroller配置為2頁(spine位於中央)或者雙面,則需要建立2個content view controller並放入數組。

然後,將數組對象賦給view controller並將導航方向設定為向前模式:

 
[pageController setViewControllers:viewControllers
      direction:UIPageViewControllerNavigationDirectionForward
     animated:NO
     completion:nil]; 
 

最後,將page vview controller加到當前視圖:

 
[self addChildViewController:pageController];
 [[self view] addSubview:[pageController view]];
 [pageController didMoveToParentViewController:self]; 

 

運行 UIPageVIewController 應用

點擊Run,運行程式。第1頁將顯示出來。從右至左滑動螢幕,將翻到下一頁,做相反方向滑動則翻到上一頁。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.