iOS6开发----应用集合视图(UICollectionView)-创建基于Storyboard的集合视图应用程序
关于集合视图UICollectionView的相关文章:
第三十一部分:应用集合视图(UICollectionView)-使用xib文件创建集合视图单元格 第三十一部分:应用集合视图(UICollectionView)-创建UICollectionViewCell子类单元格
创建基于Storyboard的集合视图应用程序
前面创建SimpleCollectionView范例程序的时候,我们取消了Use Storyboard选项,简单演示了集合视图的一些基本概念和用法。这里,我们将更深入创建基于Storyboard的、有趣一点的集合视图应用程序。下面是最终实现的PhotoCollectionView应用程序的运行效果:
使用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画布中。
从上图可以看到,随着UICollectionViewController加入到Storyboard中,同时,一个UICollectionView对象(黑色背景)和一个原型单元格(左上角的一个白色方形格子)也加入到场景中。 接下来,我们在项目中添加UICollectionViewController子类。选择File > New > File… 菜单项,在iOS Cocoa Touch节点下,选择Objective-C Class。
在接下来的窗口中,设置类名为PhotoCollectionViewController,Subclass of下拉菜单中选择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大小占满整个单元格,我们将在单元格中显示图像。
因为需要对单元格中的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对象,显示该对象的连接信息,如下图所示。
下一步定义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应用程序运行效果所示,每一个单元格显示一张固定尺寸的图像。