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

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

#import <UIKit/UICollectionViewFlowLayout.h>
#import "ZFFlowLayoutMacro.h"
#import "ZFFlowLayoutProtocol.h" //流水布局类型
typedef enum : NSUInteger {
FlowLayoutType_leftAlign,
FlowLayoutType_rightAlign,
} FlowLayoutType; @interface ZFFlowLayout : NSObject /*!
* @author zhoufei
*
* @brief 根据传入不同的流失布局类型获取不同的布局实例
* @param flowLayoutType 流水布局类型
* @return 布局实例
*/
+ (UICollectionViewFlowLayout *)flowLayoutWithFlowLayoutType:(FlowLayoutType)flowLayoutType; /*!
* @author zhoufei
*
* @brief 自定义布局实例:根据传入不同的流失布局类型,item距离四周距离,section距离四周距离 自定义布局实例
* @param flowLayoutType 流水布局类型
* @param itemEdgeInsets 第一个item距离四周的距离
* @param sectionEdgeInsets section距离四周的距离
* @return 布局实例
*/
+ (UICollectionViewFlowLayout<ZFFlowLayoutProtocol> *)flowLayoutWithFlowLayoutType:(FlowLayoutType)flowLayoutType
ItemEdgeInsets:(FlowLayoutItemEdgeInsets)itemEdgeInsets
sectionEdgeInsets:(FlowLayoutSectionEdgeInsets)sectionEdgeInsets;

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

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

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

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

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

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

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

- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray* attributes = [[super layoutAttributesForElementsInRect:rect] mutableCopy]; NSMutableArray * subArray = [LayoutAttributeTools groupTheSameLineItems:attributes]; [self leftAlign_updateItemAttributeInSigleLine:subArray]; return attributes;
} /*!
* @author zhoufei
*
* @brief 更新每个元素的位置
* @param groupArray 归并后的结果数组
*/
- (void)leftAlign_updateItemAttributeInSigleLine:(NSMutableArray * )groupArray{ NSMutableArray * modelArray = [NSMutableArray array]; for (NSArray * array in groupArray) { NSInteger count = array.count; if (!count) {
continue;
} for (int i = ; i<count; i++) {
UICollectionViewLayoutAttributes *attrOne = array[i];
[modelArray addObject:[Attribute AttributeWithIndex:i width:attrOne.size.width]]; } CGFloat leftWith = ; for (int i=; i<count; i++) { UICollectionViewLayoutAttributes *attr = [array objectAtIndex:i]; NSPredicate *predice =[NSPredicate predicateWithFormat:@"index < %d",i];
NSArray * resultArray = [modelArray filteredArrayUsingPredicate:predice];
NSNumber * number = [resultArray valueForKeyPath:@"@sum.width"]; leftWith = self.leftMargin+self.itemMargin*i+number.doubleValue; CGRect frame = attr.frame;
frame.origin.x = leftWith;
attr.frame = frame; }
[modelArray removeAllObjects];
} }
上面这个方法- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
是父类 UICollectionViewFlowLayout的代理方法,在这个方法中可以拿到当前屏幕中显示的所有 UICollectionViewCell的布局实现,我们对
UICollectionViewCell的布局修改也就是在这个方法中。
首先通过方法 [LayoutAttributeTools groupTheSameLineItems:attributes];对屏幕中显示的每一行 UICollectionViewCell 进行分组。这样分组之后逻辑比较清晰。只需要设置每一行UICollectionViewCell的新布局实例,剩余的也都是有每一行组成的。直接来个循环就搞定了。
方法 [self leftAlign_updateItemAttributeInSigleLine:subArray];就是对分组后的UICollectionViewCell进行逐行更新布局实例对象的值。具体实现已经在代码中给出了。 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. 常用linux命令及其设置

    完成一个运维的工作,以下的命令和配置是经常会用到的,总结一下工作以来的命令和配置 linux常用命令 linux客户端挂接(mount)其他linux系统或UNIX系统的NFS共享 $ mkdir – ...

  2. Java线程池使用和分析(二) - execute()原理

    相关文章目录: Java线程池使用和分析(一) Java线程池使用和分析(二) - execute()原理 execute()是 java.util.concurrent.Executor接口中唯一的 ...

  3. linux cut命令详解

    cut是一个选取命令,就是将一段数据经过分析,取出我们想要的.一般来说,选取信息通常是针对"行"来进行分析的,并不是整篇信息分析的. (1)其语法格式为:cut  [-bn] [f ...

  4. tolua#代码简要分析

    简介 tolua#是Unity静态绑定lua的一个解决方案,它通过C#提供的反射信息分析代码并生成包装的类.它是一个用来简化在C#中集成lua的插件,可以自动生成用于在lua中访问Unity的绑定代码 ...

  5. 文本处理sed常用操作

    文本处理sed常用操作 linux sed (stream editor) is a Unix utility that parses and transforms text, using a sim ...

  6. JS基础与循环

    JS 简介 [JS的三种方式] 1.HTML标签中内嵌JS <button onclick="javascript:alert('白痴')">呵呵呵</butto ...

  7. 实时Android语音对讲系统架构

    本文属于Android局域网内的语音对讲项目系列,<通过UDP广播实现Android局域网Peer Discovering>实现了局域网内的广播及多播通信,本文将重点说明系统架构,音频信号 ...

  8. react基于nodejs简单的搭建与开发方法

    只需安装babel命令,即可将react的jsx写法转换成浏览器认识的js写法 1.安装nodejs(百度下载安装即可,自带npm) 2.cmd打开命令行,cd进入在自己的文件夹下 执行命令: npm ...

  9. 谈一下我们是如何开展code review的

    众所周知,代码审查是软件开发过程中十分重要的环节,楼主结合自己的实际工作经验,和大家分享一下在实际工作中代码审查是如何开展的, 笔者水平有限,若有错误和纰漏,还请大家指正. 代码审查的阻力 我想不通公 ...

  10. python安装pillow模块错误

    安装的一些简单步骤就不介绍了,可以去搜索一下,主要就记录下我在安装pillow这一模块遇到的问题 1:安装好pillow后,安装过程没有出错 2:但是在python的IDLE输入from PIL im ...