UICollectionView基础学习(基本使用一)

UICollectionView基础学习

iOS6引入的集合(CollectionView)是一种网格状视图, 用来排布其中的各个单元格, 他们不仅仅是能够垂直滚动的一列单元格. 集合视图的许多概念与表格相同, 当却更强大, 也更加灵活
本次将介绍集合视图的一些基本知识, 包括他的数据源, 特殊用途, 以及单元格等. 同学们将会学到如何开发标准的集合视图与自定义的集合视图, 如何在视图中添加特效, 以及如是使用内置的动画功能来创建相当高效的交互方式

1.1 集合视图与表视图的异同

UICollectionView 实例会把各项数据展示成一份有序集合. 与表视图一样, 集合视图也有单元格, 头部及尾部构成, 而且由数据源及委托驱动, 但与表格不同的地方在于, 集合视图还引入了与布局有关的类, 这个类用来指定各个条目应该如何摆放在屏幕上, 该类负责管理各个单元格的位置, 使得对应的条目可以在必要时出现在适当的位置

对比项 集合视图 表格
主类 UICollectionView UITableView
控制器 UICollectionViewController UITableViewController
内容 单元格,补充视图(头部或者尾部), 装饰视图(背景图版及视觉装饰) 单元格, 头部, 尾部
由用户所触发的重新载入 reloadData reloadData
可复用单元格 UICollectionViewCell(通过 dequeueReuseableCellWithReuseIdentifier:forIndexPath: 获取) UITableViewCell(通过 dequeueReuseableCellWithReuseIdentifier:forIndexPath: 获取)
注册 类或 XIB 来注册可复用单元格, 补充视图以及装饰图 用类或 XIB 来注册可复用单元格
头部及尾部 UICollectionReusableView UITableViewHeaderView, UITableViewFooterView
布局 UICollectionViewLayout 及 UICollectionViewFlowLayout 不适用
数据源 UICollectionDataSource UITableViewDataSource
委托 UICollectionViewDelegate UITableViewDelegate
用于布局的委托 UICollectionViewDelegateFlowlayout 不适用
索引机制 通过区段与条目索引 通过区段与行来定位
滚动方向 水平或垂直 垂直
视觉效果 自定义设置 不适用

1.2 两者在实现层的区别
编写程序时, 构建表格视图和构建集合视图所用的代码是有几个地方不同的. 集合视图不允许相互局的延迟加载. 在创建集合视图时, 为该视图提供内容的数据源必须按时完全准备好的. 我们不能等到程序执行初始化方法, loadView 方法或者 viewDidLoad 方法的时候在准备数据源, 而是必须把他准备好.
可以再应用程序委托中准备, 也可以在实例化集合视图并将它添加到其他试图之前, 或者把集合视图控制器设置为其他控制器的子控制器之前

展示集合视图之前, 一点要把集合视图的布局对象完全准备好

    MyCollectionViewController *mcc = [[MyCollectionViewController alloc] initWithCollectionViewLayout:layout];

集合视图的生命周期中并不只能有一种布局, 可以使用 collectionViewLayout 属性来访问集合视图的布局, 修改这个属性之后, 视图就会以不带动画方式立即更新其布局, iOS7 提供了一个简单带动画的布局切换方式

    - (void)setCollectionViewLayout:animated:completion:
  1. 建立集合视图

2.1 通过控制器使用集合视图
构建控制器时, 首先创建并设置号其布局对象, 然后分配新的实例, 并用准备好的布局对象初始化

    UICollectionViewFlowLayout *layout = [[UICollectionFlowLayout alloc] init];
    layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;   // 修改滚动方向
    MyCollectionViewController *mcc = [[MyCollectionViewController alloc] initWithCollectionViewLayout:layout];

2.2 直接使用集合视图

    UICollectionViewFlowLayout *layout = [[UICollectionFlowLayout alloc] init];
    layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;   // 修改滚动方向
    collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
    collectionView.dataSource = self;
    collectionView.delegate = self;

2.3 数据源与委托

管理集合视图的视图控制器会宣称自己实现了 UICollectionViewDataSource, UICollectionViewDelegate 协议, 如果使用 FlowLayout 布局控制器还会宣称实现了 UICollectionViewDelegateFlowLayout 协议, 该协议通过一系列回调方法来个集合视图的布局对象提供布局信息

与表视图一样, 数据源提供了每个区段以及区段内每个条目的信息, 并根据需求返回对应的单元格以及集合视图上面的其他部件, 委托处理用户操作, 并对用户的改动请求作出回应, UICollectionViewDelegateFlowLayout 则负责提供该区段的详细的布局信息, 大多数情况下, 它的方法都是可选的

  1. 流式布局

3.1 滚动方向: scrollDirection 属性决定了视图中的区段是水平排列还是垂直排列, 水平滚动: 元素布局时会优先将垂直方向的空间填充完毕,然后开启下一列; 垂直滚动则优先将水平空间填充完毕,然后开启下一行

3.2 条目尺寸,行间距: minimumLineSpacing, minimumInteritemSpacing 属性规定了每个区段内条目之间的距离; 行间距( line spacing)表示连个相邻行之间的距离, 在水平布局下是垂直方向, 在垂直布局下时水平方向

3.3 头部与尾部尺寸: headerReferenceSize, footerReferenceSize 属性定义了区段的头部和尾部应该有多宽, 多高, 接收的值为 CGSize, 当为水平布局时使用宽度字段, 垂直布局时, 使用高度字段

以上2,3属性均可以在 UICollectionViewDelegateFlowLayout 中设置

collectionView:layout:sizeForItemAtIndexPath --- 方法与 itemSize 属性相对应, 他可以指定具体每个条目尺寸

collectionView:layout:minimumLineSpacingForSectionAtInde: --- 方法与 minimumLineSpacing 属性对应, 他可以具体到每个区段内的最小行间距

collectionView:layout:minimumInteritemSpacingForSectionAtInde: --- 方法与 minimumInteritemSpacing 属性相对应, 他可以具体控制每个区段内的最小条目间距

collectionView:layout:referenceSizeForHeaderInSection: --- 与 headerReferenceSize 相对应

collectionView:layout:referenceSizeForHeaderInSection: --- 与 footerReferenceSize 相对应

3.4 内边距: 最小行距及最小条目间距属性定义了区段内的某个条目与其他条目之间的位置关系, 与之对应 sectionInset 属性则描述了区段内所有条目的总体边界与外围的集合视图的边界

上代码: 1.
采用流式布局的简单集合视图

    1. 在 storyBoard 中创建一个 UICollectionViewController

    2.
    #import <UIKit/UIKit.h>

    @interface ViewController : UICollectionViewController

    @end
    
    #import "ViewController.h"

    @interface ViewController ()<UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>
    @property (nonatomic, assign) BOOL useHeader;
    @property (nonatomic, assign) BOOL useFooter;
    @property (nonatomic, assign) NSInteger numberOfSectin;
    @property (nonatomic, assign) NSInteger itemsInSection;
    @end
    
    @implementation ViewController
    
    - (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout *)layout
    {
        if (self = [super initWithCollectionViewLayout:layout]) {
            
        }
        return self;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.useFooter = NO;
        self.useHeader = NO;
        self.numberOfSectin = 1;
        self.itemsInSection = 10;
        // 注册 Cell
        [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"];
        // 注册 Header
        [self.collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header"];
        // 注册 Footer
        [self.collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"footer"];
        
        self.collectionView.backgroundColor = [UIColor lightGrayColor];
        
        // 允许用户多选
        self.collectionView.allowsMultipleSelection = YES;
    
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    #pragma mark - UICollectionViewDataSource
    - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
    {
        return self.numberOfSectin;
    }
    
    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
    {
        return self.itemsInSection;
    }
    
    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
        UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
        cell.backgroundColor = [UIColor whiteColor];
        cell.selectedBackgroundView = [[UIView alloc] initWithFrame:CGRectZero];
        cell.selectedBackgroundView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5f];
        return cell;
    }
    
    - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
    {
        if (kind == UICollectionElementKindSectionHeader) {
            UICollectionReusableView *header = [self.collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header" forIndexPath:indexPath];
            header.backgroundColor = [UIColor blackColor];
            return header;
        } else if (kind == UICollectionElementKindSectionFooter) {
            UICollectionReusableView *footer = [self.collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"footer" forIndexPath:indexPath];
            footer.backgroundColor = [UIColor darkGrayColor];
            return footer;
        }
        return nil;
    }
    
    #pragma mark - UICollectionViewDelegate
    - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
    {
        NSLog(@"Selected item at indexPath: %@", indexPath);
    }
    
    - (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath
    {
        NSLog(@"Deselect item at indexPath: %@",indexPath);
    }
    
    #pragma mark - UICollectionViewDelegateFlowLayout
    // header 大小
    - (CGSize) collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
    {
        return self.useHeader ? CGSizeMake(60.0, 30.0) : CGSizeZero;
    }
    
    /// footer 大小
    - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section
    {
        return self.useFooter ? CGSizeMake(60.0, 30.0) : CGSizeZero;
    }
    
    @end

<img src="http://upload-images.jianshu.io/upload_images/536129-62df25095adb23b9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" width = "320" height = "480" alt="图片名称" align=center />

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容

  • 翻译自“Collection View Programming Guide for iOS” 0 关于iOS集合视...
    lakerszhy阅读 3,782评论 1 22
  • 概述 UICollectionView是iOS开发中最常用的UI控件之一,可以用它来管理一组有序的不同尺寸的视图,...
    渐z阅读 2,936评论 0 3
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,079评论 25 707
  • 创建自定义布局 在开始创建自定义布局之前,考虑清楚是否有这个必要。UICollectionViewFlowLayo...
    丨n水瓶座菜虫灬阅读 571评论 0 0
  • 本来就是一颗石头,敲裂了,却用水泥来补,以后的岁月里,除了长年累月水滴石穿,再也没有什么可以滋润它的心。而即使水滴...
    帅气的昵称LB阅读 158评论 0 0