【iOS官方文档翻译】UICollectionView与UICollectionViewFlowLayout

(一)先来简单回顾一下UICollectionView
*UICollectionView的简单使用可以看我以前写的这篇博文:UICollectionView的基本使用

UICollectionView与UITableView很相似,必须实现两个代理:UICollectionViewDataSource和UICollectionViewDelegate,但是UICollectionView的展示的内容布局可以比UITableView更为多变和灵活,这主要是通过设置UICollectionView的collectionViewLayout属性来实现的。collectionViewLayout为UICollectionViewLayout抽象类的实例,一下是苹果官方对UICollectionViewLayout的简介:

(二)UICollectionViewLayout

UICollectionViewLayout类是一个抽象类,你可以继承它并生成collection view的布局信息。它的任务是决定cell、supplementary view和decoration view(关于这几个视图,看图1)的放置位置并且回应collection view的布局信息请求。然后collection view为对应的视图申请所提供的布局信息,以便它们能展示到屏幕上。


图1


根据上面苹果官方的说明,就是需要新建一个继承自UICollectionViewLayout的类,但是在这之前,苹果让我们先看看UICollectionViewFlowLayout类,这是苹果已经帮我们建立好的一个继承自UICollectionViewLayout的类,如果我们的布局并非十分特殊或复杂,并且是使用的流水布局(或网格布局),使用UICollectionViewFlowLayout将使得一切更为简单。下面看下官方对UICollectionViewFlowLayout的解释:

(三)UICollectionViewFlowLayout

UICollectionViewFlowLayout类用来管理网格布局(下文统一称为grid)中每一个项目视图、section的头部和尾部视图的具体布局。collection视图中的每一行(或一列)由尽可能多的cell来填充满,一行(或一列)放不下后,流动到下一行(或下一列),其中每一个cell的大小可以是一样的或不一样的。

一个flow layout与collection view的代理一起决定grid中每一个section中的每一项的大小、头部、尾部。代理对象须遵从UICollectionViewDelegateFlowLayout协议。使用代理可以动态地调节布局信息。例如,使用代理对象来说明grid中的每个cell使用不同的大小。如果不提供代理,flow layout会使用通过对象属性来设置的值作为默认值。

Flow layouts在排列内容时,会在某一个方向上使用固定的距离值,而在另一个方向上使用可滑动的距离值,例如,在一个垂直的可滑动grid中,内容的宽度是固定的(受限于collection view的宽度),而内容的高度是根据section和item的数目自动调节的。layout默认被设定为垂直的,可以使用scrollDirection 属性来修改滚动方向。

flow layout中每一个section都可以有自定义的头部或尾部。为了配置头部和尾部的view,必须设置头部或尾部的大小不为0。可以通过实现合适的代理方法或者给headerReferenceSize 和footerReferenceSize 属性设置合适的值。如果头部和尾部的大小是0,对应的view是不会添加到collectionview中的。

(四)下面是官方API中关于 UICollectionViewFlowLayout的一些常用属性

@property(nonatomic) UICollectionViewScrollDirection scrollDirection
grid的滑动方向

@property(nonatomic) CGFloat minimumLineSpacing
每行之间最小的距离

@property(nonatomic) CGFloat minimumInteritemSpacing 
每一行中每个item间的最小的距离

@property(nonatomic) CGSize itemSize
每一个items的默认大小

@property(nonatomic) CGSize estimatedItemSize
每一个items的估计大小(iOS8之后的属性,只要设置了estimatedItemSize,collection view 就会根据 cell 里面的 autolayout 约束去确定cell 的大小)

@property(nonatomic) UIEdgeInsets sectionInset
section里面内容的页边空白

@property(nonatomic) CGSize headerReferenceSize
section头部的默认大小

@property(nonatomic) CGSize footerReferenceSizesection
section尾部的默认大小

(五) UICollectionViewFlowLayout属性实例

下面我们就是用下面这篇博文中的示例代码来实践一下UICollectionViewFlowLayout:

UICollectionView的基本使用 :http://blog.csdn.net/dolacmeng/article/details/45583681


先看下不设置UICollectionView的collectionViewLayout属性时的效果(但是原来的示例代码使用了UICollectionViewDelegateFlowLayout代理中的sizeForItemAtIndexPath方法来设置cell的大小):



然后我们试一下使用UICollectionViewFlowLayout,我们修改viewDidLoad方法为如下:

- (void)viewDidLoad {
    [super viewDidLoad];
    UICollectionViewFlowLayout *floatLayout = [[UICollectionViewFlowLayout alloc] init];
    floatLayout.itemSize = CGSizeMake(100, 100); //设置每个cell的大小
    floatLayout.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10);//设置内容的内边距
    floatLayout.minimumInteritemSpacing = 5;//设置每个cell之间的最小间距
    floatLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;//设置滚动方向
    _collectionview.collectionViewLayout = floatLayout;
}


*因为修改UICollectionViewFlowLayout的属性值相当于修改了对应的默认值,因为最终的布局是由UICollectionViewFlowLayout和UICollectionViewDelegateFlowLayout代理方法共同决定,而我们已经实现了sizeForItemAtIndexPath方法,会覆盖itemSize属性的值,所以同时还要屏蔽掉sizeForItemAtIndexPath方法:

//-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
//        return CGSizeMake(120, 120);
//}


运行之后就得到了下图的效果(cell的尺寸缩小了/内边框为10/水平滚动):

(五)UICollectionViewFlowLayout方法实例

上面的示例中只是简单修改了视图的属性,有时候我们需要实现更多的显示需求,此时可以新建一个继承自UICollectionViewFlowLayout的类,并重写UICollectionViewFlowLayout父类中的一些方法:

- (CGSize)collectionViewContentSize
返回collection view的内容宽度和高度

(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
返回在给定的范围(rectangle)内所有cell的布局属性

(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
返回指定位置的item的布局属性

(UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
Returns the layout attributes for the specified supplementary view.
返回具体某个supplementary view的布局属性

- (UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString *)decorationViewKind atIndexPath:(NSIndexPath *)indexPath
返回具体某个decoration view的布局属性

(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
询问是否在显示的边界发生改变就进行重新布局

- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset
                                 withScrollingVelocity:(CGPoint)velocity

返回滑动后的内容偏移量(滑动所停止的点),默认返回proposedContentOffset参数的值,可以在这里返回我们实际需要的偏移量,详见Demo

- (void)prepareForCollectionViewUpdates:(NSArray *)updateItems
Notifies the layout object that the contents of the collection view are about to change.
通知布局对象collectionview的内容将要发生变化

实例代码可以参考我以前写的两篇博文:

iOS用UICollectionView实现Gallery效果
iOS UICollectionView实现瀑布流






  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值