zoukankan      html  css  js  c++  java
  • UICollectionView 总结

    这个视图是我遇到的 UIView 里面最复杂的吧。。。感觉学好了这个,UIScrollView 和 UITableView 都不算啥了。。。

    UICollectionView有两个主要的特点:

    其一:和tableView一样,即提供数据的UICollectionViewDataSource以及处理用户交互的UICollectionViewDelegate;

    其二,对于cell的样式和组织方式,由于collectionView比tableView要复杂得多,因此没有按照类似于tableView的style的方式来定义,而是专门使用了一个类来对collectionView的布局和行为进行描述,这就是UICollectionViewLayout。这不仅是collectionView和tableView的最重要求的区别,也是整个UICollectionView的精髓所在。

    1)基本视图

    最简单的 UICollectionView 就是一个 GridView,可以以多列的方式将数据进行展示。标准的UICollectionView包含三个部分,它们都是UIView的子类:

    • Cells:用于展示内容的主体,对于不同的cell可以指定不同尺寸和不同的内容
    • Supplementary Views 追加视图 (类似Header或者Footer)
    • Decoration Views 装饰视图 (用作背景展示,只在 UICollectionViewLayout 中提供)

    2)视图的注册和重用

    相比 UITableView 有两个主要变化:一是加入了对某个 Class 的注册,这样即使不用提供nib而是用代码生成的 view 也可以被接受为 cell 了;二是不仅只是 cell,supplementaryView也可以用注册的方法绑定初始化了。在对collection view的重用ID注册后,就可以像UITableView那样简单的写cell配置了:

    在使用 UICollectionView 的时候,初始化一个 layout 给这个 UICollectionView,并且注册相应的 cell 和 supplementaryView,这样在之后的重用方法中,就没有必要像 UITableView 一样判断是否有 cell 或 supplementaryView——要是在重用队列里没有可用的cell的话,runtime将自动帮我们生成并初始化一个可用的cell.

    3)cell

    UICollectionView 的 cell 相对 UITableView 简单,由下而上分别为:

    • cell :本身作为容器 view;
    • backgroundView:cell 的背景;
    • selectedBackgroundView:cell 被选中时的背景
    • contentView:自定义内容会添加到这个 view 上。

    4)UICollectionViewLayout

    负责了将各个cell、Supplementary View和Decoration Views进行组织,为它们设定各自的属性——layoutAttributes。

    Layout决定了UICollectionView是如何显示在界面上的。在展示之前,一般需要生成合适的UICollectionViewLayout子类对象,并将其赋予CollectionView的collectionViewLayout属性。

    Apple为我们提供了一个最简单可能也是最常用的默认layout对象:UICollectionViewFlowLayout。Flow Layout简单说是一个直线对齐的layout,最常见的Grid View形式即为一种Flow Layout配置。

    UICollectionViewFlowLayout 的重要属性有:

    • itemSize:定义了每一个item的大小。通过设定itemSize可以全局地改变所有cell的尺寸,也可以定制尺寸
    • spacing:指定 item 之间间距和每一行之间的间距,可以全局设置或者定制间距
    • scrollDirection:确定 scroll view 的方向,将影响 Flow Layout 的基本方向和由 header 及 footer 确定的 section 之间的宽度
    • header 和 footer:同样可以全局设置或者定制。根据滚动方向不同,高和宽中只有一个会起作用:垂直滚动时section间宽度为该尺寸的高,而水平滚动时为宽度起作用
    • sectionInset:section 的缩进

    5)UICollectionViewLayoutAttributes——这个类包含的属性有:

    1 @property (nonatomic) CGRect frame
    2 @property (nonatomic) CGPoint center
    3 @property (nonatomic) CGSize size
    4 @property (nonatomic) CATransform3D transform3D
    5 @property (nonatomic) CGFloat alpha
    6 @property (nonatomic) NSInteger zIndex
    7 @property (nonatomic, getter=isHidden) BOOL hidden

    UICollectionViewLayoutAttributes的实例中包含了诸如边框,中心点,大小,形状,透明度,层次关系和是否隐藏等信息。和DataSource的行为十分类似,当UICollectionView在获取布局时将针对每一个indexPath的部件(包括cell,追加视图和装饰视图),向其上的UICollectionViewLayout实例询问该部件的布局信息(在这个层面上说的话,实现一个UICollectionViewLayout的时候,其实很像是封装一个delegate,之后的例子中会很明显地看出),这个布局信息,就以UICollectionViewLayoutAttributes的实例的方式给出。

    6)自定义UICollectionViewLayout

    UICollectionViewLayout的功能为向UICollectionView提供布局信息,不仅包括cell的布局信息,也包括追加视图和装饰视图的布局信息。实现一个自定义layout的常规做法是继承UICollectionViewLayout类,然后重载下列方法:

    //返回collectionView的内容的尺寸
    -(CGSize)collectionViewContentSize
    //返回rect中的所有的元素的布局属性,一个包含UICollectionViewLayoutAttributes的NSArray
    -(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
    //UICollectionViewLayoutAttributes可以是cell,追加视图或装饰视图的信息,通过不同的UICollectionViewLayoutAttributes初始化方法可以得到不同类型的UICollectionViewLayoutAttributes:
    layoutAttributesForCellWithIndexPath:
    layoutAttributesForSupplementaryViewOfKind:withIndexPath:
    layoutAttributesForDecorationViewOfKind:withIndexPath:
    //返回对应于indexPath的位置的cell的布局属性
    -(UICollectionViewLayoutAttributes )layoutAttributesForItemAtIndexPath:(NSIndexPath )indexPath
    //返回对应于indexPath的位置的追加视图的布局属性,如果没有追加视图可不重载
    -(UICollectionViewLayoutAttributes )layoutAttributesForSupplementaryViewOfKind:(NSString )kind atIndexPath:(NSIndexPath *)indexPath
    //返回对应于indexPath的位置的装饰视图的布局属性,如果没有装饰视图可不重载
    -(UICollectionViewLayoutAttributes * )layoutAttributesForDecorationViewOfKind:(NSString)decorationViewKind atIndexPath:(NSIndexPath )indexPath
    //当边界发生改变时,是否应该刷新布局。如果YES则在边界变化(一般是scroll到其他地方)时,将重新计算需要的布局信息。
    -(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds

    5)自定义 UICollectionViewLayout

    在初始化一个UICollectionViewLayout实例后,会有一系列准备方法被自动调用,以保证layout实例的正确:

    首先,-(void)prepareLayout将被调用,默认下该方法什么没做,但是在自己的子类实现中,一般在该方法中设定一些必要的layout的结构和初始需要的参数等。

    之后,-(CGSize) collectionViewContentSize将被调用,以确定collection应该占据的尺寸。注意这里的尺寸不是指可视部分的尺寸,而应该是所有内容所占的尺寸。collectionView的本质是一个scrollView,因此需要这个尺寸来配置滚动行为。

    接下来-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect被调用,这个没什么值得多说的。初始的layout的外观将由该方法返回的UICollectionViewLayoutAttributes来决定。

    另外,在需要更新layout时,需要给当前layout发送 -invalidateLayout,该消息会立即返回,并且预约在下一个loop的时候刷新当前layout,这一点和UIView的setNeedsLayout方法十分类似。在-invalidateLayout后的下一个collectionView的刷新loop中,又会从prepareLayout开始,依次再调用-collectionViewContentSize和-layoutAttributesForElementsInRect来生成更新后的布局。

  • 相关阅读:
    Golang Channel用法简编
    一个有关Golang变量作用域的坑
    Goroutine是如何工作的
    Go语言是如何处理栈的
    Go与C语言的互操作
    Lua虚拟机初始化
    lua 函数调用 -- 闭包详解和C调用
    c++对象导出到lua
    nginx缓存设置proxy_cache
    golang中map并发读写问题及解决方法
  • 原文地址:https://www.cnblogs.com/xiayao/p/5330332.html
Copyright © 2011-2022 走看看