为UICollectionViewFlowLayout添加maximumInteritemSpacing

UICollectionViewFlowLayout

是苹果为我们实现的一个布局,它有两个属性可以设置cell之间的间距:minimumLineSpacing 设置最小行间距,minimumInteritemSpacing 设置同一列中间隔的cell最小间距。
为什么是最小,而不是固定的间距呢?因为 FlowLayout 的实现是两端对齐,同时保持一列中的cell间距相等。
像这样的:


142014942.png

可以看到,一列中的cell总是两端和collectionView对齐,cell之间的间隔一致。

需求

那么现在有一个需求就是,不想要两端对齐,而是左对齐。cell根据间距和size,从左往右一个个的排,排不下了换一行。
像这样的:


屏幕快照 2016-01-05 上午11.03.46.png

这里引入一个 maximumInteritemSpacing 的属性。这个属性和 minimumInteritemSpacing 类似,用来设置两个同一列的相邻的cell之间的最大间距。
相邻的cell之间的实际间距 spacing 总是要满足:

minimumInteritemSpacing <= spacing <= maximumInteritemSpacing

实现

1:创建一个 UICollectionViewFlowLayout 子类 CustomFlowLayout

@interface CustomFlowLayout : UICollectionViewFlowLayout
@property (nonatomic) CGFloat maximumInteritemSpacing; 
@end

2:在CustomerFlowLayout的实现里,由于系统已经帮我们做了全部的计算的事情。所以我们只需要重写 -layoutAttributesForElementsInRect: 这个方法即可。并不需要重写其他方法。

- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
    //使用系统帮我们计算好的结果。
    NSArray *attributes = [super layoutAttributesForElementsInRect:rect];

    //第0个cell没有上一个cell,所以从1开始
    for(int i = 1; i < [attributes count]; ++i) {
        //这里 UICollectionViewLayoutAttributes 的排列总是按照 indexPath的顺序来的。
        UICollectionViewLayoutAttributes *curAttr = attributes[i];
        UICollectionViewLayoutAttributes *preAttr = attributes[i-1];
   
        NSInteger origin = CGRectGetMaxX(preAttr.frame);  
        //根据  maximumInteritemSpacing 计算出的新的 x 位置
        CGFloat targetX = origin + _ maximumInteritemSpacing;
        // 只有系统计算的间距大于  maximumInteritemSpacing 时才进行调整
        if (CGRectGetMinX(curAttr.frame) > targetX) {
            // 换行时不用调整
            if (targetX + CGRectGetWidth(curAttr.frame) < self.collectionViewContentSize.width) {
                CGRect frame = curAttr.frame;
                frame.origin.x = targetX;
                curAttr.frame = frame;
            }
        }
    }
    return attributes;
}

当然,maximumInteritemSpacing 应该有一个默认值:

- (void)awakeFromNib
{
    [super awakeFromNib];
    self. maximumInteritemSpacing = 8.f;
}

使用方法

CustomFlowLayout 可以在xib和storyboard中使用。你往控制器里拖进去一个UICollectionView时会自动携带一个 UICollectionViewFlowLayout,修改它的类名为 CustomerFlowLayout 即可。

屏幕快照 2016-01-05 上午11.31.36.png

效果图

屏幕快照 2016-01-05 上午11.32.33.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,815评论 1 92
  • UICollection是iOS6的时候引入的,它是同UITableview共享一套API设计,都是基于datas...
    今天又要上班吗阅读 1,854评论 5 9
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,259评论 4 61
  • 学习不是为了毕业,不是为了考试,而是为了积累。迈出学校大门后,拼什么?拼持续不断学习的能力。现实生活中要体现你与他...
    王玲玲Casey阅读 1,994评论 4 3
  • 我的耳机属于我,不属于别人,包括他自己。但是,他最近不太乖,我才他可能是厌烦我了,因为我最近感冒了,我总是躺在床上...
    sid_9ff8阅读 181评论 0 0