在iOS 6 发布前,开发人员习惯使用UITableView来展示几乎所有类型的数据集合。ios 6 为 IOS 引入了全新的控制器,用来显示数据集合,集合视图控制器是与表视图控制器类似的全新UI框架。。

下面讲解下一些重要的类与协议,它们是你在实现集合视图时必须知道 的。

  • UICollectionViewController

这个类的功能与UITableViewController类似。它负责管理集合视图、存储所需的数据,并且能处理数据源与委托协议。

1、UICollectionViewCell

它与UITableViewCell很像。你通常不需要创建UITableViewCell,可以调用 dequeueReusableCellWithReuseIdentifier:方法从集合视图中获取。

MKPhotoCell *cell = (MKPhotoCell*) [collectionView dequeueReusableCellWithReuseIdentifier:

orientation == PhotoOrientationLandscape ? CellIdentifierLandscape:CellIdentifierPortrait

forIndexPath:indexPath];

2、UICollectionViewDataSource

猜到了吧,它与UITableViewDataSource方法类似。数据源协议拥有需要在UICollectionViewController的子类中实现的方法。

3、UICollectionViewDelegate

要在集合视图中处理选中或高亮事件,就得实现委托协议中的方法。

下面能过具体的Demo向大家介绍下UICollectionViewController的用法:

首先在Xcode中创建一个单视图应用。在第二个窗格中,选择Use Storyboards、Use Automatic Reference Counting以及Choose iPad as the target device复选框并点击Next按钮,然后再选择想要保存的位置。

1、编辑 storyboard

打开 MainStoryboard.storyboard文件并删除其中唯一的视图控制器。从对象库中拖出一个UICollectionViewController类。确保这个控制器被设置为故事板的初始视图控制器。

现在,在工程中打开唯一的视图控制器的头文件。将基类从UIViewController改成 UICollectionViewController,并实现UICollectionViewDataSource 与 UICollectionViewDelegate协议。回到故事板,将集合视图控制器的类名改成MKViewController(或者使用任意其它的前缀)。构建并运行应用,ios模拟器中会出现一个黑色的屏幕。

2、添加集合视图单元

看到这样的结果并不能使你满足,对吧?我们来给它加点料吧。首先,添加一个UICollectionViewCell的子类。我们取名为MKPhotoCell。打开你的故事板并在集合视图控制器中选择唯一的集合视图单元。将它的类更改为MKPhotoCell.在Utilities(实用工具)窗格打开属性检查器并将标识符设置为 MKPhotoCell。这一步非常重要。在后面的代码中,你将会使用这个标识符来(dequeue)出列单元.如图所示:

添加一个空白的UIView作为你的集合视图单元的子视图,并把视图背景色改为红色。

3、实现数据源方法

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {

return100;

}

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {

return 1;

}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

MKPhotoCell *cell = (MKPhotoCell*) [collectionView dequeueReusableCellWithReuseIdentifier:@"MKPhotoCell"

forIndexPath:indexPath];

return cell;

}

现在构建并运行应用。你将会看到有100个单元的栅格,每一个单元都是红色的。很神奇吧,当你旋转iPad到横向时会更惊奇:栅格会自动旋转并对齐。

4、显示图片

现在可以用一些更加有趣的东西来替换这些红色的子视图。这里我们要显示某个目录中的图片。把一些图片大约50张复制到你的工程中去。移除在上一节中添加的红色子视图,并添加一个UIImageView和一个UILabel到UICollectionViewCell中。

5、准备数据源

实现方法是遍历目录中的文件。把它添加到集合视图控制器子类的viewDidLoad方法中。

NSArray * photosArray = [[NSFileManagerdefaultManager] contentsOfDirectoryAtPath:[selfphotosDirectory] error:nil];

self.photosList = photosArray;

然后定义photosDirectory方法:

-(NSString*) photosDirectory

{

return [[[NSBundlemainBundle] resourcePath] stringByAppendingPathComponent:@"Photos"];

}

现在,更新数据源方法,使其返回这些信息数据。上节代码返回的是一个区和100个项。将数值100改成self.photosList数组。

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

MKPhotoCell *cell = (MKPhotoCell*) [collectionView dequeueReusableCellWithReuseIdentifier:@"MKPhotoCell"

forIndexPath:indexPath];

NSString *photoName = [self.photosList objectAtIndex:indexPath.row];

NSString *photoFilePath = [[self photosDirectory] stringByAppendingPathComponent:photoName];

cell.nameLabel.text =[photoName stringByDeletingPathExtension];

UIImage *image = [UIImage imageWithContentsOfFile:photoFilePath];

UIGraphicsBeginImageContext(CGSizeMake(128.0f, 128.0f));

[image drawInRect:CGRectMake(0, 0, 128.0f, 128.0f)];

cell.photoView.image = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

return cell;

}

 

现在构建并运行应用,你将会看到图片整齐地按照行列排列。

6、支持横屏与竖屏图片

在故事板中创建另一个UICollectionViewCell并将它的类更改为MKPhotoCell.改变图片视图的大小以适应竖屏,之前的旧的单元方向则是横屏。你可以为横屏使用180*120大小,为竖屏单元使用120*180大小。MKPhotoCell大小为200*250. 更改它们的cellIdentifier,比如改成MKPhotoCellLandscape 和 MKPhotoCellPortrait这样的。完成之后,故事板应该是这样的:

7、判定方向

现在你必须根据图片的方向来决定使用哪个单元。可以通过创建UIImage然后读取它的size属性来获取图片的方向。如果图片的宽度大于高度,则是横向;否则就是竖向。如果你在collectionView cellForItemAtIndexPath:方法中进行计算的话,滚动速度肯定会受影响,我们在viewDidLoad方法中计算。代码如下:

- (void)viewDidLoad

{

[superviewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

NSArray * photosArray = [[NSFileManagerdefaultManager] contentsOfDirectoryAtPath:[selfphotosDirectory] error:nil];

self.photosCache = [NSMutableDictionarydictionary];

self.photoOrientation = [NSMutableArrayarray];

self.photosList = nil;

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

[photosArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

NSString *path = [[selfphotosDirectory] stringByAppendingPathComponent:obj];

CGSize size = [UIImage imageWithContentsOfFile:path].size;

if(size.width > size.height)

[self.photoOrientationaddObject:[NSNumbernumberWithInt:PhotoOrientationLandscape]];

else

[self.photoOrientationaddObject:[NSNumbernumberWithInt:PhotoOrientationPortrait]];

}];

dispatch_async(dispatch_get_main_queue(), ^{

self.photosList = photosArray;

[self.collectionViewreloadData];

});

});

}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

static NSString *CellIdentifierLandscape = @"MKPhotoCellLandscape";

static NSString *CellIdentifierPortrait = @"MKPhotoCellPortrait";

int orientation = [[self.photoOrientation objectAtIndex:indexPath.row] integerValue];

MKPhotoCell *cell = (MKPhotoCell*) [collectionView dequeueReusableCellWithReuseIdentifier:

orientation == PhotoOrientationLandscape ? CellIdentifierLandscape:CellIdentifierPortrait

forIndexPath:indexPath];

NSString *photoName = [self.photosList objectAtIndex:indexPath.row];

NSString *photoFilePath = [[self photosDirectory] stringByAppendingPathComponent:photoName];

cell.nameLabel.text =[photoName stringByDeletingPathExtension];

__block UIImage* thumbImage = [self.photosCache objectForKey:photoName];

cell.photoView.image = thumbImage;

if(!thumbImage) {

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

UIImage *image = [UIImage imageWithContentsOfFile:photoFilePath];

if(orientation == PhotoOrientationPortrait) {

UIGraphicsBeginImageContext(CGSizeMake(180.0f, 120.0f));

[image drawInRect:CGRectMake(0, 0, 180.0f, 120.0f)];

thumbImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

} else {

UIGraphicsBeginImageContext(CGSizeMake(120.0f, 180.0f));

[image drawInRect:CGRectMake(0, 0, 120.0f, 180.0f)];

thumbImage = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();

}

dispatch_async(dispatch_get_main_queue(), ^{

[self.photosCache setObject:thumbImage forKey:photoName];

cell.photoView.image = thumbImage;

});

});

}

return cell;

}

 

构建并运行应用。应该可以横竖屏切换了。因为篇幅问题,暂不处理点击事件了。

原文:http://www.cnblogs.com/javawebsoa/archive/2013/05/24/3098089.html

UICollectionViewController用法的更多相关文章

  1. UICollectionViewController的用法1

    UICollectionView 和 UICollectionViewController 类是iOS6 新引进的API,用于展示集合视图,布局更加灵活,可实现多列布局,用法类似于UITableVie ...

  2. IOS中UICollectionView和UICollectionViewController的用法

    1.新建一个xib描述UICollectionViewCell(比如DealCell.xib),设置好resuse identifier(比如deal) 2.控制器继承UICollectionView ...

  3. iOS开发之窥探UICollectionViewController(五) --一款炫酷的图片浏览组件

    本篇博客应该算的上CollectionView的高级应用了,从iOS开发之窥探UICollectionViewController(一)到今天的(五),可谓是由浅入深的窥探了一下UICollectio ...

  4. iOS开发之窥探UICollectionViewController(四) --一款功能强大的自定义瀑布流

    在上一篇博客中<iOS开发之窥探UICollectionViewController(三) --使用UICollectionView自定义瀑布流>,自定义瀑布流的列数,Cell的外边距,C ...

  5. iOS开发之窥探UICollectionViewController(一) -- Ready Your CollectionViewController

    之前用CollectionViewController只是皮毛,一些iOS从入门到精通的书上也是泛泛而谈.这几天好好的搞了搞苹果的开发文档上CollectionViewController的内容,亲身 ...

  6. UICollectionView在Swift3.0中的用法

    UICollectionView在Swift3.0中的用法 UICollectionView的初始化跟OC中是相似的,创建 GameView 集成自 UICollectionView .注意不同于UI ...

  7. iOS开发之UICollectionViewController

    1.概述 UICollectionView控件主要是用来做九宫格的,类似于android中的GridView控件.其用法与UITableView一样,首先要使控制器遵守数据源协议,再将控制器设置为UI ...

  8. EditText 基本用法

    title: EditText 基本用法 tags: EditText,编辑框,输入框 --- EditText介绍: EditText 在开发中也是经常用到的控件,也是一个比较必要的组件,可以说它是 ...

  9. jquery插件的用法之cookie 插件

    一.使用cookie 插件 插件官方网站下载地址:http://plugins.jquery.com/cookie/ cookie 插件的用法比较简单,直接粘贴下面代码示例: //生成一个cookie ...

随机推荐

  1. Android Home键状态保存运用场景

    当我们在一个Activity中有接收Intent过来的值,或者当前Activity有保存数据时候,如果此时不小心按到了Home键,然后没有及时回来而是运行了其它应用程序,当你想起来的时候,恐怕已经是几 ...

  2. 获取技能的成功经验和关于C语言学习的调查 2015528

    内容提要 你有什么技能比大多人(超过90%以上)更好?针对这个技能的获取你有什么成功的经验?与老师博客中的学习经验有什么共通之处? 有关C语言学习的调查 你是怎么学习C语言的?(作业,实验,教材,其他 ...

  3. Google Map API key 获取方法

    要想使用google map api 必须从google网站上获取key之后才有权限使用,但是要想申请key必须要有证明书,也就是所谓的MD5.下面一步一步来说明: 步骤1: 如果你使用的是eclip ...

  4. CDC类

    CDC :class of device context Windows使用与设备无关的图形设备环境(DC :Device Context) 进行显示 .MFC基础类库定义了设备环境对象类----CD ...

  5. Orchard常见问题

    本文链接:http://www.cnblogs.com/souther/p/4543299.html 什么是Orchard Orchard是一个免费,开源,注重社区的项目,其目标是提供ASP.NET平 ...

  6. 手把手教你Linux服务器集群部署.net网站 - Linux系统安装和设置

    在开源软件已成趋势化的今天,微软这‘老古董’也开始向开源方向发力,这对我们.NET开发者是极大的喜讯.而在开源软件中, Linux就是其中一个优秀的代表,几乎各行业和计算机有关的都有它的身影,其中一点 ...

  7. EntityFramework中的线程安全,又是Dictionary

    继上次记一次w3wp占用CPU过高的解决过程(Dictionary和线程安全)后又再次与Dictionary博弈,这一次是在EntityFramework中的Dictionary. 从一个异常说起 这 ...

  8. [BZOJ2879][Noi2012]美食节(最小费用最大流动态加边)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2879 分析: 和bzoj1070一样,但这题的数据范围大了很多,如果直接建图就会TLE ...

  9. 机器学习中的矩阵方法(附录A): 病态矩阵与条件数

    1. 病态系统 现在有线性系统: Ax = b, 解方程 很容易得到解为: x1 = -100, x2 = -200. 如果在样本采集时存在一个微小的误差,比如,将 A 矩阵的系数 400 改变成 4 ...

  10. 03.C#委托(二章1.1)

    一章1.5-1.8介绍的是com.动态类型及.NET平台一些说明,每个心中都有自己的标准,听一家之言,叫人不爽,相信自己有自己的标准和自己的编程理念就OK了,也不想码那么多说明性的文字,直接跳过吧,当 ...