使用CollectionView时,其中一个注意点就是:一定要在创建CollectionView时,创建一个布局样式
通常我们可以在CollectionView的类中,在构造函数方法内创建一个布局,但是在设置布局相关属性时,还需注意设置时机,也就是在哪个方法中进行设置,比如在viewDidLoad、viewWillAppear等方法中,视图并未真实显示,这时获取到的Frame并不是真实数据,往往我们会在viewDidLayoutSubviews或viewDidAppear方法内进行设置,这样就能完成CollectionView的创建,CollectionViewLayout的创建以及设置.
这种方式的缺点就是代码都写在了一个类文件中,封装性差
UICollectionViewLayout中,为我们提供了一个对象方法
// The collection view calls -prepareLayout once at its first layout as the first message to the layout instance.
// The collection view calls -prepareLayout again after layout is invalidated and before requerying the layout information.
// Subclasses should always call super if they override.
- (void)prepareLayout;
该方法的特点是:
在CollectionView的第一次布局的时候被调用,此时CollectionView的frame已经设置完毕
所以只需抽取一个继承自UICollectionViewFlowLayout的类,将布局部分的代码全部写在该类中,在创建CollectionView的时候,直接使用抽取的FlowLayout来设置布局即可
#import "FlowLayout.h"
#import <UIKit/UIKit.h>
@interface FlowLayout : UICollectionViewFlowLayout
@end
-------------------------------------------------------------------------
@implementation FlowLayout
- (void)prepareLayout{
[super prepareLayout];
self.itemSize = self.collectionView.bounds.size;
self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
self.minimumLineSpacing = 0;
self.minimumInteritemSpacing = 0;
self.collectionView.showsVerticalScrollIndicator = NO;
self.collectionView.showsHorizontalScrollIndicator = NO;
self.collectionView.bounces = NO;
self.collectionView.pagingEnabled = YES;
}
@end
通过这种方式,在使用CollectionView的时候,抽取了一个FlowLayout类,一个Cell类,加上一个CollectionView/CollectionViewController,减轻了CollectionView/CollectionViewController中的代码量,并且可读性更高
补充点:
使用CollectionView与TableView一样,需要考虑Cell重用问题,而CollectionView系统默认只提供了通过IndexPath的方式来创建Cell,当我们抽取Cell,重写Init方法时会发现自定义Cell不执行init方法,如果直接在init中设置Cell视图,会发现视图叠加显示的现象,而当我们重写initWithFrame方法设置Cell视图时就不会出现这样的情况,可以解决Cell重用的问题