UICollectionViewController用法
在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用法的更多相关文章
- UICollectionViewController的用法1
UICollectionView 和 UICollectionViewController 类是iOS6 新引进的API,用于展示集合视图,布局更加灵活,可实现多列布局,用法类似于UITableVie ...
- IOS中UICollectionView和UICollectionViewController的用法
1.新建一个xib描述UICollectionViewCell(比如DealCell.xib),设置好resuse identifier(比如deal) 2.控制器继承UICollectionView ...
- iOS开发之窥探UICollectionViewController(五) --一款炫酷的图片浏览组件
本篇博客应该算的上CollectionView的高级应用了,从iOS开发之窥探UICollectionViewController(一)到今天的(五),可谓是由浅入深的窥探了一下UICollectio ...
- iOS开发之窥探UICollectionViewController(四) --一款功能强大的自定义瀑布流
在上一篇博客中<iOS开发之窥探UICollectionViewController(三) --使用UICollectionView自定义瀑布流>,自定义瀑布流的列数,Cell的外边距,C ...
- iOS开发之窥探UICollectionViewController(一) -- Ready Your CollectionViewController
之前用CollectionViewController只是皮毛,一些iOS从入门到精通的书上也是泛泛而谈.这几天好好的搞了搞苹果的开发文档上CollectionViewController的内容,亲身 ...
- UICollectionView在Swift3.0中的用法
UICollectionView在Swift3.0中的用法 UICollectionView的初始化跟OC中是相似的,创建 GameView 集成自 UICollectionView .注意不同于UI ...
- iOS开发之UICollectionViewController
1.概述 UICollectionView控件主要是用来做九宫格的,类似于android中的GridView控件.其用法与UITableView一样,首先要使控制器遵守数据源协议,再将控制器设置为UI ...
- EditText 基本用法
title: EditText 基本用法 tags: EditText,编辑框,输入框 --- EditText介绍: EditText 在开发中也是经常用到的控件,也是一个比较必要的组件,可以说它是 ...
- jquery插件的用法之cookie 插件
一.使用cookie 插件 插件官方网站下载地址:http://plugins.jquery.com/cookie/ cookie 插件的用法比较简单,直接粘贴下面代码示例: //生成一个cookie ...
随机推荐
- 从0开始学Java——从jsp到servlet转换的各种辅助元素介绍
1. 指示元素,<%@指示元素 [属性=值]* %> 其中指示元素包括page, include, 和tablib三个. 其中 属性=值 可以有多对. 其中page用来告知容器如何转译目 ...
- Windows下虚拟机安装Mac OS X ----- VM12安装Mac OS X 10.11
Windows下虚拟机安装Mac OS X -– VM12安装Mac OS X 10.11 随着Iphone在国内大行其道,越来越多的开发者涌入iOS开发大军 中,但都苦于没有苹果机,本文即将介绍WI ...
- 网络封包分析工具Charles使用
网址:http://www.charlesproxy.com/ 截取网络封包的工具. 简介 Charles是在Mac下常用的截取网络封包的工具,在做iOS开发时,我们为了调试与服务器端的网络通讯协议, ...
- 【转载】UVa 11464 Even Parity 偶数矩阵
题意:给你一个n*n的01矩阵,让你把这个矩阵中尽量少的0转换成1,使得矩阵每个位置的上下左右四个相邻的数加起来能被2整除,求最少的转换数 首先,n 的规模并不大,最大只有15.但是完全枚举整个矩阵显 ...
- 你的C#代码是怎么跑起来的(一)
写了那么多C#代码,大家有没有想过自己写的代码编译后的可执行文件内部是什么样子,是怎样在系统上运行的? 编译成exe,然后双击exe文件运行,这中间到底发生了些什么呢,这篇先来剖析下exe内部的样子: ...
- 傻傻分不清楚的php脚本路径
闲话就不说了,还是直接提出今天的问题,准确的说,对多个相似的 有关当前脚本信息的全局变量常量的区分. 先贴上代码: <?php echo $_SERVER['PHP_SELF']; echo ...
- 一个优秀的Android应用从建项目开始
1.项目结构 现在的MVP模式越来越流行.就默认采用了.如果项目比较小的话: app——Application Activity Fragment Presenter等的顶级父类 config——AP ...
- HTML5+NodeJs实现WebSocket即时通讯
声明:本文为原创文章,如需转载,请注明来源WAxes,谢谢! 最近都在学习HTML5,做canvas游戏之类的,发现HTML5中除了canvas这个强大的工具外,还有WebSocket也很值得注意.可 ...
- Bootstrap2和3的区别
如果你需要兼容IE8甚至是IE7和IE6,那么只能选择Bootstrap2,虽然它自身在IE6的效果也并不完美. 但是倘若你跟随时代的脚步,并且面向的客户也很高端大气上档次地选择只需要兼容高级 ...
- [Aaronyang] 写给自己的WPF4.5 笔记[2依赖属性]
人生的意义不在于拿一手好牌,而在于打好一手坏牌 --Aaronyang的博客(www.ayjs.net)-www.8mi.me =============时隔两年后再看WPF========== 因为 ...