1。简单介绍与说明
简介:UICollectionView提供了一种自定义布局展示试图内容的方式。
说明:涉及到的必须的基本类型与基本代理类型有UICollectionView/UICollectionViewCell/UICollectionViewLayout/UICollectionViewLayoutAttributes/
UICollectionViewDelegate,一般情况下有上述几个就可以了。
UICollectionViewCell显示的单元格,UICollectionView是容纳单元格的容器,UICollectionViewLayout定义布局,UICollectionViewLayoutAttributes单
定义单个cell的布局与显示相关属性。
2.使用方法:
a.创建UICollectionView,设置dataSource,并在dataSource里面实现必要的方法(类似UITableView的)。
b.创建cell:datasource中创建cell,在datasource方法中,这里与UITableview不同,只要在controllerload的时候调用registerClass:forCellWithReuseIdentifier:或者类似的方法设置cell的类型,然后就能在dataSource必须的方法实现collectionView:cellForItemAtIndexPath:中使用dequeueReusableCellWithReuseIdentifier:forIndexPath:方法就能获取到一个已经创建好的cell,在这里对其进行一些必要的设置就行。
c.设置layout:调用UICollectionView的setCollectionViewLayout:方法设置对应的layout。
d。实现layout:UICollectionViewLayout是一个抽象类,你可以使用系统已经提供的UICollectionViewFlowLayout,也可以自己定义一个。(初学者可以直接使用UICollectionViewFlowLayout作为第一次练习,然后自己实现一个layout来明白其中原理)
3.layout原理与注意项:
UICollectionViewLayout是一个抽象的类型,所以在使用的时候需要使用他的子类,IOS本身提供了一个UICollectionViewFlowLayout做简单布局,当然也可以自己派生自己的layout,这时候需要注意:
layout本身一定要处理所有与位置相关的操作,UICollectionView本身的一些与布局相关的方法不能在这里使用比如:visibleCells:/indexPathsForVisibleItems:).实际上,UICollectionView的这些方法就是通过调用layout的相关方法来实现的,同理的还有numberOfSections:同类的方法通过调用datasource来实现的。
通过上面说明,我们可以想象到,自定义的layout必须能够单独实现layout的相关功能,比如计算某个rect中可见cell的indexPath,并能获取到每个cell的layout attribuate,获取整个UICollectionView的contentSize等等。
实际上,在UICollectionViewLayout中定义的方法并不是完全的,也并不是完全必须的(其中两个就是可选的,可以查看官方文档),但是实现必须的方法,是需要其他的功能辅助.子类需要实现的方法在头文件中列在SubclassingHooks下面。
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect;
- (CGSize)collectionViewContentSize;
以上三个方法是在子类中必须实现的,
第一个方法获取某个indexPath下cell的LayoutAttributes信息;
最后一个是计算整个UICollectionView的contentSize,如果计算的大了,有可能会引起crash(具体情况取决于超出的尺寸是否会导致新的cell出现)
第二个获取在某个区域内(以contentSize为依据)可见cell的Attributes信息,这个函数需要获取这个可见区域内的indexPath的范围,而获取indexPath范围的方法需要获取某个点上cell的indexPath的方法,而这个方法又依赖于每个cell的size。
所以实现自定义方法至少还需要在实现上述三个方法之外多实现三个功能点。
没办法加上附件,有一个简单的代码在github上。
代码github地址