天天看點

Storyboard建立使用UICollectionViewController

建立基于Storyboard的集合視圖應用程式

前面建立SimpleCollectionView範例程式的時候,我們取消了Use Storyboard選項,簡單示範了集合視圖的一些基本概念和用法。這裡,我們将更深入建立基于Storyboard的、有趣一點的集合視圖應用程式。下面是最終實作的PhotoCollectionView應用程式的運作效果:

Storyboard建立使用UICollectionViewController

使用Xcode 的Single View Application 模闆,建立一個新的項目PhotoCollectionView,類字首設定為Photo。同時,選擇Use Storyboards和Use Automatic Reference Counting複選框。

删除模闆中的視圖控制器

根據前面選擇的模闆建立的Xcode項目,Xcode自動建立了UIViewController的子類。這個示例項目中,我們需要的是UICollectionViewController子類。是以,選擇項目導航欄中的PhotoViewController.h和PhotoViewController.m檔案,删除這兩個檔案。

接着,選擇MainStoryboard.storyboard檔案,在Storyboard畫布中,選擇視圖控制器,點選鍵盤delete鍵,删除視圖控制器。

添加集合視圖控制器(Collection View Controller)到Storyboard中

從對象庫中拖拉Collection View Controller對象到Storyboard畫布中。

Storyboard建立使用UICollectionViewController

從上圖可以看到,随着UICollectionViewController加入到Storyboard中,同時,一個UICollectionView對象(黑色背景)和一個原型單元格(左上角的一個白色方形格子)也加入到場景中。

接下來,我們在項目中添加UICollectionViewController子類。選擇File > New > File… 菜單項,在iOS Cocoa Touch節點下,選擇Objective-C Class。

在接下來的視窗中,設定類名為PhotoCollectionViewController,Subclass of下拉菜單中選擇UICollectionViewController。

Storyboard建立使用UICollectionViewController

項目中将增加2個新檔案PhotoCollectionViewController.h和PhotoCollectionViewController.m檔案,是UICollectionViewController的子類。

打開Storyboard檔案,選擇Collection視圖控制器,在Identity inspector面闆視窗設定Class 屬性為剛剛建立的PhotoCollectionViewController類。

添加集合視圖單元格類(Collection View Cell Class)

再次選擇File > New > File … 菜單項,然後在iOS Cocoa Touch節點中,選擇Objective-C Class 模闆。在接下來的視窗中,輸入類名PhotoCollectionViewCell,Subclass of 下拉菜單中選擇UICollectionViewCell。點選Next 按鈕,選擇檔案在項目中存放位置,接着點選Create 按鈕,建立集合視圖單元格子類。

傳回MainStoryboard.storyboard檔案,選擇集合視圖中左上角白色方形格子,這個就是集合視圖的原型單元格(Prototype Cell)。然後,在Identity inspector面闆視窗,設定Class屬性為前面建立的PhotoCollectionViewCell。

在Attributes inspector面闆視窗,設定Identifier屬性為photoCell,後面的代碼中會用到這個重用辨別符(reuse identifier)。

設計原型單元格

前面已經完成了集合視圖和集合視圖單元格類的設計。現在我們開始設計單元格,設計單元格就是簡單地從對象庫拖拉一些UI元素到單元格設計界面上。單元格的尺寸大小可以直接進行拖拉或者在Size inspector面闆視窗設定。

下面,我們調整單元格的大小,并從對象庫拖拉Image View對象到單元格中,Image View大小占滿整個單元格,我們将在單元格中顯示圖像。

Storyboard建立使用UICollectionViewController

因為需要對單元格中的Image View進行指派,是以需要定義Image View的輸出口。顯示Assistant Editor編輯器,同時顯示PhotoCollectionViewCell.h代碼檔案,按住Control鍵,拖拉Image View 對象到頭檔案中,位于@interface代碼行下面。在彈出視窗中,選擇OutLet,輸入imageView作為輸出口,建立Image View對象到輸出口之間的連接配接。連接配接完成之後的PhotoCollectionView.h代碼如下所示:

#import <UIKit/UIKit.h> @interface PhotoCollectionViewCell : UICollectionViewCell @property (strong, nonatomic) IBOutlet UIImageView *imageView; @end

OK,現在單元格的實作工作已經完成了。

實作資料模型(Data Model)

本示例項目的資料模型是一系列的圖像檔案,每一個圖像都将顯示在集合視圖的每一個單元格中。

第一步是向項目中加載圖像檔案。首先,我們在項目中建立一個新的檔案夾(group),命名為Images。然後從Finder中拖拉一些需要顯示的圖像到該檔案夾中。

接着,我們打開PhotoCollectionViewControlller.h 檔案,定義一個可變數組photoImages變量,用來存放圖像檔案名稱。

#import <UIKit/UIKit.h> @interface PhotoCollectionViewController : UICollectionViewController @property (strong, nonatomic) NSMutableArray *photoImages; @end

最後,打開PhotoCollectionViewController.m檔案,修改viewDidLoad方法,初始化數組為圖像檔案名。

- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.photoImages = [@[ @"IMG_1.JPG", @"IMG_2.JPG", @"IMG_3.JPG", @"IMG_4.JPG", @"IMG_5.JPG", @"IMG_6.JPG", @"IMG_7.JPG", @"IMG_8.JPG", @"IMG_9.JPG", @"IMG_10.JPG", @"90s-girl.jpg", @"90s-girl-1.jpg", @"90s-girl-2.jpg", @"90s-girl-3.jpg"] mutableCopy]; }

注意上述代碼,我們使用了Modern Objective-C 文法來初始化數組,等同于下面的代碼(之前的文法)來初始化數組。上述文法預設建立的是不可變數組,是以在後面添加了mutableCopy方法的調用,傳回可變數組。

self.photoImages = [[NSMutableArray alloc] initWithObjects: @"IMG_1.JPG", @"IMG_2.JPG", @"IMG_3.JPG", @"IMG_4.JPG", @"IMG_5.JPG", @"IMG_6.JPG", @"IMG_7.JPG", @"IMG_8.JPG", @"IMG_9.JPG", @"IMG_10.JPG", @"90s-girl.jpg", @"90s-girl-1.jpg", @"90s-girl-2.jpg", @"90s-girl-3.jpg", nil];

實作資料源(Data Source)

我們知道集合視圖需要一個資料源(Data Source)和一個委托(Delegate)才能提供所有的功能。預設情況下,Xcode指派PhotoCollectionViewController類同時作為UICollectionView對象的委托和資料源。我們可以選擇Storyboard中的UICollectionView對象來驗證一下,右擊UICollectionView對象,顯示該對象的連接配接資訊,如下圖所示。

Storyboard建立使用UICollectionViewController

下一步定義PhotoCollectionViewController 類要實作的協定。另外,這個類需要和PhotoCollectionViewCell 類互動,現在也正好引入對應的頭檔案。更新之後的PhotoCollectionViewController.h檔案如下所示:

#import <UIKit/UIKit.h> #import "PhotoCollectionViewCell.h" @interface PhotoCollectionViewController : UICollectionViewController @property (strong, nonatomic) NSMutableArray *photoImages; @end

下面實作一系列遵守UICollectionVeiwDataSource協定的資料源方法。首先是讓集合視圖知道需要顯示多少個section。針對本示例程式,我們僅顯示一個section。打開PhotoCollectionViewController.m檔案,編寫numberOfSectionsInCollectionView:方法,傳回數字1。

#pragma mark - #pragma mark UICollectionViewDataSource

-(NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView { return 1; }

集合視圖調用的另外一個方法是了解每一個section中有多少個資料項顯示。在示例程式中,我們需要數組中的每一個圖像顯示在一個單元格中。

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return self.photoImages.count; }

集合視圖調用的下一個方法是cellForItemAtIndexPath。該方法從重用隊列中擷取一個單元格對象,接着根據indexPath參數,從photoImages數組中擷取圖像,配置并傳回單元格對象。

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { PhotoCollectionViewCell *myCell = [collectionView dequeueReusableCellWithReuseIdentifier:@"photoCell" forIndexPath:indexPath];

UIImage *image; int row = [indexPath row]; image = [UIImage imageNamed:self.photoImages[row]]; myCell.imageView.image = image; return myCell; }

測試PhtotoCollectionView應用程式

編譯運作應用程式,如一切正常,将在集合視圖中顯示圖像清單,如前面PhotoCollectionView應用程式運作效果所示,每一個單元格顯示一張固定尺寸的圖像。