在平时使用的app中会经常碰到一些规格选择,筛选,标签等页面,这些页面的布局展示通常是左对齐流水布局。
实现类似这样的左对齐流水布局有多种方式,如果选项少的话可以直接用UIButton实现。现在我们有一种比较简单的方式可以实现这个目的。
就是对UICollectionView稍加改动,就能轻松实现。
下面介绍一下具体实现的方法。

通过 ZFFlowLayout类可以创建一个默认距离的布局实例,也可以创建一个自定义距离的布局实例。

  1. #import <UIKit/UICollectionViewFlowLayout.h>
  2. #import "ZFFlowLayoutMacro.h"
  3. #import "ZFFlowLayoutProtocol.h"
  4.  
  5. //流水布局类型
  6. typedef enum : NSUInteger {
  7. FlowLayoutType_leftAlign,
  8. FlowLayoutType_rightAlign,
  9. } FlowLayoutType;
  10.  
  11. @interface ZFFlowLayout : NSObject
  12.  
  13. /*!
  14. * @author zhoufei
  15. *
  16. * @brief 根据传入不同的流失布局类型获取不同的布局实例
  17. * @param flowLayoutType 流水布局类型
  18. * @return 布局实例
  19. */
  20. + (UICollectionViewFlowLayout *)flowLayoutWithFlowLayoutType:(FlowLayoutType)flowLayoutType;
  21.  
  22. /*!
  23. * @author zhoufei
  24. *
  25. * @brief 自定义布局实例:根据传入不同的流失布局类型,item距离四周距离,section距离四周距离 自定义布局实例
  26. * @param flowLayoutType 流水布局类型
  27. * @param itemEdgeInsets 第一个item距离四周的距离
  28. * @param sectionEdgeInsets section距离四周的距离
  29. * @return 布局实例
  30. */
  31. + (UICollectionViewFlowLayout<ZFFlowLayoutProtocol> *)flowLayoutWithFlowLayoutType:(FlowLayoutType)flowLayoutType
  32. ItemEdgeInsets:(FlowLayoutItemEdgeInsets)itemEdgeInsets
  33. sectionEdgeInsets:(FlowLayoutSectionEdgeInsets)sectionEdgeInsets;

调用如下方法可以根据想要创建的布局类型,生成一个布局实现。

  1. + (UICollectionViewFlowLayout *)flowLayoutWithFlowLayoutType:(FlowLayoutType)flowLayoutType;

调用如下方法可以根据想要创建的布局类型和第一个item距离四周的距离与section距离四周的距离,生成一个自定义的布局实现。

  1. + (UICollectionViewFlowLayout<ZFFlowLayoutProtocol> *)flowLayoutWithFlowLayoutType:(FlowLayoutType)flowLayoutType
  2. ItemEdgeInsets:(FlowLayoutItemEdgeInsets)itemEdgeInsets
  3. sectionEdgeInsets:(FlowLayoutSectionEdgeInsets)sectionEdgeInsets;
  4.  
  5. 在第二个方法中使用到了自定义的枚举和结构体,它们的具体实现如下:
  1. #ifndef ZFFlowLayoutMacro_h
  2. #define ZFFlowLayoutMacro_h
  3.  
  4. /*!**
  5. 左对齐布局时:左上角第一个item 距离四周的距离
  6. 右对齐布局时:右上角第一个item 距离四周的距离
  7. ***/
  8. typedef struct FlowLayoutItemEdgeInsets {
  9. CGFloat top, left, bottom, right; // specify amount to inset (positive) for each of the edges. values can be negative to 'outset'
  10. } FlowLayoutItemEdgeInsets;
  11.  
  12. /*!** item所属的组section 距离四周的距离 ***/
  13. typedef struct FlowLayoutSectionEdgeInsets {
  14. CGFloat top, left, bottom, right; // specify amount to inset (positive) for each of the edges. values can be negative to 'outset'
  15. } FlowLayoutSectionEdgeInsets;
  16.  
  17. #endif /* ZFFlowLayoutMacro_h */

结构体中值得具体含义已经在注释中写出,这里就不在讲了。

下面讲一下最核心的类 LeftAlignedFlowLayout类

因为这个类代码略有点长,这里就这贴出主要的逻辑代码:

  1. - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
  2. {
  3. NSMutableArray* attributes = [[super layoutAttributesForElementsInRect:rect] mutableCopy];
  4.  
  5. NSMutableArray * subArray = [LayoutAttributeTools groupTheSameLineItems:attributes];
  6.  
  7. [self leftAlign_updateItemAttributeInSigleLine:subArray];
  8.  
  9. return attributes;
  10. }
  11.  
  12. /*!
  13. * @author zhoufei
  14. *
  15. * @brief 更新每个元素的位置
  16. * @param groupArray 归并后的结果数组
  17. */
  18. - (void)leftAlign_updateItemAttributeInSigleLine:(NSMutableArray * )groupArray{
  19.  
  20. NSMutableArray * modelArray = [NSMutableArray array];
  21.  
  22. for (NSArray * array in groupArray) {
  23.  
  24. NSInteger count = array.count;
  25.  
  26. if (!count) {
  27. continue;
  28. }
  29.  
  30. for (int i = ; i<count; i++) {
  31. UICollectionViewLayoutAttributes *attrOne = array[i];
  32. [modelArray addObject:[Attribute AttributeWithIndex:i width:attrOne.size.width]];
  33.  
  34. }
  35.  
  36. CGFloat leftWith = ;
  37.  
  38. for (int i=; i<count; i++) {
  39.  
  40. UICollectionViewLayoutAttributes *attr = [array objectAtIndex:i];
  41.  
  42. NSPredicate *predice =[NSPredicate predicateWithFormat:@"index < %d",i];
  43. NSArray * resultArray = [modelArray filteredArrayUsingPredicate:predice];
  44. NSNumber * number = [resultArray valueForKeyPath:@"@sum.width"];
  45.  
  46. leftWith = self.leftMargin+self.itemMargin*i+number.doubleValue;
  47.  
  48. CGRect frame = attr.frame;
  49. frame.origin.x = leftWith;
  50. attr.frame = frame;
  51.  
  52. }
  53. [modelArray removeAllObjects];
  54. }
  55.  
  56. }
  1. 上面这个方法- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
  1. 是父类 UICollectionViewFlowLayout的代理方法,在这个方法中可以拿到当前屏幕中显示的所有 UICollectionViewCell的布局实现,我们对
  1. UICollectionViewCell的布局修改也就是在这个方法中。
    首先通过方法 [LayoutAttributeTools groupTheSameLineItems:attributes];对屏幕中显示的每一行 UICollectionViewCell 进行分组。这样分组之后逻辑比较清晰。只需要设置每一行UICollectionViewCell的新布局实例,剩余的也都是有每一行组成的。直接来个循环就搞定了。
    方法 [self leftAlign_updateItemAttributeInSigleLine:subArray];就是对分组后的UICollectionViewCell进行逐行更新布局实例对象的值。具体实现已经在代码中给出了。
  2.  
  3. Demo地址:https://github.com/zhfei/ZFFlowLayout

欢迎star。

如果发现不对的地方欢迎批评和指正。

UICollectionView左对齐流水布局、右对齐流水布局的更多相关文章

  1. [No000089]String的(补空位)左对齐,(补空位)右对齐

    using System; namespace Chinese中文排序Sort { internal class Program { /// <summary> /// 取子字符串 /// ...

  2. LI 标签中让文章标题左对齐,日期右对齐的方法

    希望实现标题在左对齐,日期在右对齐,当直接给日期的span加上float:right时,IE8和FF都OK,但IE6/7则会换行,下面给出一个简单有效的解决办法. <!DOCTYPE html  ...

  3. DIV左、中、右三列布局的各类情况说明

    一.中间定宽.左.右侧百分比自适应: 1.HTML代码: <div id="left"> <div id="innerLeft"> &l ...

  4. form中label标签对齐,内容右对齐

    给label设置一个固定长度即可: label{      display:inline-block;      width:100px; text-align:right;    }

  5. flex布局实现elment容器布局

    一.flex布局是什么 flex布局,意为"弹性布局",是一种响应式的布局方法 采用 Flex 布局的元素,称为 Flex 容器,它的所有子元素自动成为容器成员. 先放上一个ele ...

  6. display:flex 布局教程,弹性布局!

    display:flex 布局教程 布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现. ...

  7. Flex布局如何实现最后一个元素右对齐,或者第一个元素左对齐

    先来看看一个例子 在一个div我们把四个按钮全部放到右边去了,看下效果↓ 这个时候我们想把第一个按钮左对齐,其他保持不变 这时候我们来个第一个按钮样式上加上 :margin-right: auto; ...

  8. Bootstrap3基础 text-right/left/center 设置标题右对齐、左对齐、居中

      内容 参数   OS   Windows 10 x64   browser   Firefox 65.0.2   framework     Bootstrap 3.3.7   editor    ...

  9. 音频采样中left-or right-justified(左对齐,右对齐), I2S时钟关系

    音频采样中left-or right-justified(左对齐,右对齐), I2S时钟关系 原创 2014年02月11日 13:56:51 4951 0 0 刚刚过完春节,受假期综合症影响脑袋有点发 ...

随机推荐

  1. 在jsp中用一数组存储了数据库表中某一字段的值,然后在页面中输出其中的值。

    List<String> list = new ArrayList<String>();  String sql = "select userName from us ...

  2. react中,constructor和getInitialState的区别

    1,ES6语法 使用class声明一个类,且要继承react组件的方法和属性的时候 : 在里面我们可以直接指定 this.state = { }, 我们可以当前组件内任何地方使用 this.setSt ...

  3. JAVA经典算法40题

    1: JAVA经典算法40题 2: [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 3 ...

  4. 初探CSRF在ASP.NET Core中的处理方式

    前言 前几天,有个朋友问我关于AntiForgeryToken问题,由于对这一块的理解也并不深入,所以就去研究了一番,梳理了一下. 在梳理之前,还需要简单了解一下背景知识. AntiForgeryTo ...

  5. MongoDB数据库安装及配置环境终极教程(windows10系统)

    本文是笔者花时间踩坑踩生气了写出来的!转载请注明出处@http://www.cnblogs.com/tim100/!请尊重我的劳动成果!谢谢! 今天,给大家说说在windows10系统下MongoDB ...

  6. SEO,搜索引擎优化原理方法等整体把握

    SEO 搜索算法: 全文文字 title 标签,title里面的文字 link 链接 link 链接里的文字 站点信任度 最佳实践: 一.设置title 准确的描述当前网页的内容 提高站点内title ...

  7. java面试题—精选30道Java笔试题解答(一)

    下面都是我自己的答案非官方,仅供参考,如果有疑问或错误请一定要提出来,大家一起进步啦~~~ 1. 下面哪些是Thread类的方法() A start() B run() C exit() D getP ...

  8. __read_mostly变量含义

     1. 定义 __read_mostly原语将定义的变量为存放在.data.read_mostly段中,原型在include/asm/cache.h 中定义: #define __read_mos ...

  9. Java中多线程同步类 CountDownLatch

    在多线程开发中,常常遇到希望一组线程完成之后在执行之后的操作,java提供了一个多线程同步辅助类,可以完成此类需求: 类中常见的方法: 其中构造方法:CountDownLatch(int count) ...

  10. js 数字递增特效 仿支付宝我的财富 HTML5

    上周五应着公司临时需求,一天的时间解决掉官网(ps:比较简单哈哈),需求里面有一个特效就是数字递增到指定的数值,其实JS写也不复杂的,但是我发现一个js小插件,这个插件轻巧简单,用起来也非常简单实用. ...