UICollectionView之自定义布局

     如果有以下需求才使用自定义布局:


1.想要的布局不是栅格或者线性的,或者需要在不止一个方向滚动。

2.频繁需要更改cell的位置,更改流布局还不如自定义一个时。

自定义布局的难点在于计算布局中每个item的位置,如果有了位置,就很简单了。

继承UICollectionViewLayout

     需要实现的核心任务:

1.指定滚动区域的尺寸

2.为布局中的每一个cell或view指定attribute对象,从而使collection view得到item的位置。
     在布局过程中,使用collectionView属性从数据源获取数据。

理解核心布局过程

     集合视图和布局对象协同工作,只要集合视图需要布局信息,就向布局对象询问。集合视图第一次出现,或者尺寸改变都会获取布局信息,可以显式调用invalidateLayout方法强制重新布局。
     invalidateLayout与reloadData区别很大,重新布局不会刷新数据。在数据源中的数据变化时,reloadData才是合适的。

在布局过程中,集合视图调用了布局对象中的几个特定方法:

     1.在prepareLayout方法中完成布局信息的预处理。

     2.在collectionViewContentSize中基于预处理完成全部计算。

     3.在layoutAttributesForElementsInRect:中返回设定好的attribute。
     
     invalidateLayout方法并不会马上开始布局更新,仅仅标记了布局需要更新,在下一次视图更新循环中,集合视图发现布局需要更新时,才会更新布局。

生成布局属性


     布局属性是UICollectionViewLayoutAttributes类的对象,使用以下方法生成布局属性:

1.layoutAttributesForCellWithIndexPath:

2.layoutAttributesForSupplementaryViewOfKind:withIndexPath:

3.layoutAttributesForDecorationViewOfKind:withIndexPath:

     至少为布局属性设置尺寸和位置,zIndex用于防止重叠,isEqual:方法需要重写,集合视图调用用于某些计算。

准备布局

     在这完成准备工作。

为指定区域中的item设置attribute

     layoutAttributesForElementsInRect:方法的步骤:

1.遍历prepareLayout方法中准备的数据,填入缓存的attribute,没有就生成一个;

2.检查每个item的尺寸,看看在不在要布局的矩形区域内;

3.对于在区域内的item,添加一个对应的attribute对象到数组中

4.返回attribute对象数组

需要立刻返回布局属性的情况

     layoutAttributesForItemAtIndexPath:
     layoutAttributesForSupplementaryViewOfKind:atIndexPath:
     layoutAttributesForDecorationViewOfKind:atIndexPath:

     这些方法的实现需要取到指定item的当前布局属性并返回。每个自定义布局对象都重写实现第一个方法,如果没有supplementary view可以不重写第二个方法,如果没有decoration view可以不重写第三个方法,在这几个方法中不能更新布局属性。

让自定义布局更加迷人
     有一些方法推荐实现,效果更好。

使用附属视图为内容增色

     附属视图与cell是分离开的,有另一套布局属性。附属视图的数据来自数据源,用于说明主内容。流布局使用附属视图作为区头区尾,有的应用使用附属视图为每一个cell提供了一个说明文本。附属视图应该是UICollectionReusableView的子类。

     为布局添加附属视图的步骤:

1.在集合视图中注册附属视图,registerClass:forSupplementaryViewOfKind:withReusableIdentifier:或者
registerNib:forSupplementaryViewOfKind:withReuseIdentifier:

2.在数据源中实现collectionView:viewForSupplementaryElementOfKind:atIndexPath:方法,使用dequeueReusableSupplementaryViewOfKind:withReuseIdentifier:forIndexPath:重用或新建附属视图,设置后返回

3.像为cell设置布局属性一样为附属视图设置布局属性

4.在layoutAttributesForElementsInRect:方法的返回数组中加入附属视图的布局属性

5.实现layoutAttributesForSupplementaryViewOfKind:atIndexPath:方法,在需要时返回特定附属的布局属性

     附属视图的布局过程与cell一样,但是附属视图可以有多种附属视图样式。因为不同的cell内容可能需要有不同的附属视图来配合,附属视图有一个额外的kind字段描述。


在自定义布局中加入装饰视图
     装饰视图是用于改善集合视图外观的视图,只有外观所以不需要数据源。可以使用装饰视图实现cell的个性化。

     添加装饰视图的步骤:

1.使用registerClass:forDecorationViewOfKind:或者registerNib:forDecorationViewOfKind:注册装饰视图。

2.在布局对象的layoutAttributesForDecorationViewOfKind:atIndexPath:方法中为装饰视图设置布局属性。

3.实现layoutAttributesForDecorationViewOfKind:atIndexPath:,并在需要时返回布局属性。


4.可选实现,initialLayoutAttributesForAppearingDecorationElementOfKind:atIndexPath:和finalLayoutAttributesForDisappearingDecorationElementOfKind:atIndexPath:用于处理装饰视图的动态出现、消失效果。


     所有的配置都在initWithFrame:中完成,必须是UICollectionReusableView的子类。为装饰视图设置布局属性时,需要考虑zIndex,防止遮盖。

实现自定义布局的技巧

1.在prepareLayout方法中创建、保存稍后要用的UICollectionViewLayoutAttributes。在item少的时候缓存有效,多的时候就得考虑了。

2.不要继承UICollectionView。

3.绝不要在layoutAttributesForElementsInRect:方法中使用UICollectionView的visibleCells属性,会产生循环。有时候,布局对象需要通过数据源定位item。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值