UICollectionView总结

来源:互联网 发布:淘宝客推广渠道怎么填 编辑:程序博客网 时间:2024/05/18 16:16

简介

UICollectionView的强大之处:灵动的布局。结合动力学、交互转场、layout对象可以创造布局的无限可能。

其核心就是和UICollectionViewLayout对象的配合

UICollectionViewLayout介绍

管理布局信息,供UICV使用

基本功能
  • 使布局无效或指定某个环境的布局无效,以便将来重新布局
    public func invalidateLayout()    public func invalidateLayoutWithContext(context:  UICollectionViewLayoutInvalidationContext)
  • 添加装饰视图,不依赖UICollectionViewDataSource。牛!
public func registerClass(viewClass: AnyClass?, forDecorationViewOfKind elementKind: String)public func registerNib(nib: UINib?, forDecorationViewOfKind elementKind: String)
  • 通过重写如下方法提供自定义的布局属性对象UICollectionViewLayoutAttributes和布局无效的环境对象
public class func layoutAttributesClass() -> AnyClass public class func invalidationContextClass() -> AnyClass 
  • 准备布局。这个方法用于提高流畅度
    这是特别重要的方法,提供预处理环境。可以在这里更新数据结构和做复杂的计算。
public func prepareLayout()
  • 为UICV提供布局属性对象UICollectionViewLayoutAttributes
    这里有必须实现的方法,如果有装饰/补充视图那么以下方法都要实现。这些方法是最基础也是最重要的。
public func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? public func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes?public func layoutAttributesForSupplementaryViewOfKind(elementKind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes?public func layoutAttributesForDecorationViewOfKind(elementKind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes?
  • 根据Bounds的改变来确定是否使layout或UICollectionViewLayoutInvalidationContext对象无效
public func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool public func invalidationContextForBoundsChange(newBounds: CGRect) -> UICollectionViewLayoutInvalidationContext
  • iOS8.0 cell有方法改变布局对象提供的布局信息,也就是自己提供布局信息。这里提供方法让cell自己提供的布局信息preferredAttributes无效。
    @available(iOS 8.0, *)    public func shouldInvalidateLayoutForPreferredLayoutAttributes(preferredAttributes: UICollectionViewLayoutAttributes, withOriginalAttributes originalAttributes: UICollectionViewLayoutAttributes) -> Bool    @available(iOS 8.0, *)    public func invalidationContextForPreferredLayoutAttributes(preferredAttributes: UICollectionViewLayoutAttributes, withOriginalAttributes originalAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutInvalidationContext
  • 提供滚动停止点,用户获取这个点来做自己想做的事
public func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPointpublic func targetContentOffsetForProposedContentOffset(proposedContentOffset: CGPoint) -> CGPoint 
  • 内容尺寸,子类必须实现
public func collectionViewContentSize() -> CGSize
编辑更新功能
  • 当item被编辑(删除、添加等)或者bounds被改变,会调用以下方法
    这里的调用顺序是先于initial / final方法的,详见后面的方法。
public func prepareForCollectionViewUpdates(updateItems: [UICollectionViewUpdateItem])public func finalizeCollectionViewUpdates() public func prepareForAnimatedBoundsChange(oldBounds: CGRect) public func finalizeAnimatedBoundsChange()
  • 被编辑item的布局属性更新
    This set of methods is called when the collection view undergoes an animated transition such as a batch update block or an animated bounds change.

    • 出现动画:initialLayoutAttributesForAppearingItemAtIndexPath获取对应indexPath的刚出现时最初布局->更新后布局变化过程
    • 消失动画:更新之前的布局 ->finalLayoutAttributesForDisappearingItemAtIndexPath方法获取对应indexPath的消失时最终布局的变化过程
    public func initialLayoutAttributesForAppearingItemAtIndexPath(itemIndexPath: NSIndexPath) -> UICollectionViewLayoutAttributes?    public func finalLayoutAttributesForDisappearingItemAtIndexPath(itemIndexPath: NSIndexPath) -> UICollectionViewLayoutAttributes?    public func initialLayoutAttributesForAppearingSupplementaryElementOfKind(elementKind: String, atIndexPath elementIndexPath: NSIndexPath) -> UICollectionViewLayoutAttributes?    public func finalLayoutAttributesForDisappearingSupplementaryElementOfKind(elementKind: String, atIndexPath elementIndexPath: NSIndexPath) -> UICollectionViewLayoutAttributes?    public func initialLayoutAttributesForAppearingDecorationElementOfKind(elementKind: String, atIndexPath decorationIndexPath: NSIndexPath) -> UICollectionViewLayoutAttributes?    public func finalLayoutAttributesForDisappearingDecorationElementOfKind(elementKind: String, atIndexPath decorationIndexPath: NSIndexPath) -> UICollectionViewLayoutAttributes?

关键知识点

  • Supplementary views 并不一定会作为 header 或 footer view;他们的数量和放置的位置完全由布局控制
  • Decoration views 纯粹为一个装饰品。他们完全属于布局对象,并被布局对象管理,他们并不从 data source 获取的 contents
  • collection view 布局

    • 独立于内容的布局

      这正是你所知道的像 UITableView 和 UICollectionViewFlowLayout 这些情况。每个 cell 的位置和外观不是基于其显示的内容,但所有 cell 的显示顺序是基于内容的顺序。可以把默认的 flow layout 做为例子。每个 cell 都基于前一个 cell 放置(或者如果没有足够的空间,则从下一行开始)。布局对象不必访问实际数据来计算布局。

    • 基于内容的布局

      在很多情况下,布局对象不仅需要取出当前可见 cell 的数据,还需要从所有记录中取出一些决定当前哪些 cell 可见的数据。如果有一个依赖内容的布局,那就是暗示你需要写自定义的布局类了,同时不能使用自定义的 UICollectionViewFlowLayout,所以这正是我们需要做的事情。

  • 性能是必须考虑的因素

  • layoutAttributesForElementsInRect在可见范围内返回布局属性,不要全部返回,会影响性能
  • shouldInvalidateLayoutForBoundsChange

    最后,当 collection view 的 bounds 改变时,布局需要告诉 collection view 是否需要重新计算布局。我的猜想是:当 collection view 改变大小时,大多数布局会被作废,比如设备旋转的时候。因此,一个幼稚的实现可能只会简单的返回 YES。虽然实现功能很重要,但是 scroll view 的 bounds 在滚动时也会改变,这意味着你的布局每秒会被丢弃多次。根据计算的复杂性判断,这将会对性能产生很大的影响

  • prepareForCollectionViewUpdates跟踪更新对象,可以进行跟踪是件很酷的事情。

感悟

职责分明是写一个好框架的必要前提,当所有事情分配的井然有序,那么离成功也就不远了。我们要做的就是对职责的规划和抽离,站在高处看清问题的本质。

相关网址

UICollectionView动画
objccn.io Collection View 动画
自定义布局
UICollectionView + UIKit 力学

0 0
原创粉丝点击