【iOS开发】collectionView 瀑布流实现
一、效果展示
二、思路分析
1> 布局的基本流程
当设置好collectionView的布局方式之后(UICollectionViewFlowLayout),当系统开始布局的时候,会调用 prepareLayout 来布局
- (void)prepareLayout;
与此同时,collectionViewCell 的每个控件的布局属性都会调用 以下方法来设置(可以重写方法来修改每个cell 的数值)
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
2> 每列 的高度计算方式
1.计算所有的cell 的高度,然后平均下来,得到itemSize 然后计算每列的高度-----> 该方法不够精确,而且极端情况下会相差太大
2.每次计算cell 的时候,找出高度最低的那一列,优先添加到该列,然后依次计算------> 该方法误差较小
Tip: 在collectionView中,contentSize 就是一个摆设,不能根据这个来计算 collectionView 的大小,系统会自动的根据 itemSize 来计算
三、核心代码实现
// // WaterFall.h // 瀑布流 // // Created by gxiangzi on 15/9/16. // Copyright © 2015年 hqu. All rights reserved. // #import <UIKit/UIKit.h> @interface WaterFall : UICollectionViewFlowLayout // 计算列数 @property (assign, nonatomic) NSInteger columCount; // 所有的模型数组 @property (strong, nonatomic) NSArray * dataList; @end
// // WaterFall.m // 瀑布流 // // Created by gxiangzi on 15/9/16. // Copyright © 2015年 hqu. All rights reserved. // /** // 获得高度的办法 1. 计算总的高度,然后计算每个高度,最后设置itemsize 来计算 2. 找出最高的列,然后根据最高的列来计算 注意:collectionView 的contentView 是一个摆设,没有实际效果,需要根据 itemSize 来计算 */ #import "WaterFall.h" #import "Shop.h" @interface WaterFall () @property (nonatomic,strong) NSMutableArray * itemsAttribute; @end @implementation WaterFall -(void)prepareLayout { [super prepareLayout]; // self.sectionFootersPinToVisibleBounds = YES; // 计算每列的宽度 CGFloat contentWidth = self.collectionView.bounds.size.width - self.sectionInset.left - self.sectionInset.right; CGFloat colWidth = (contentWidth - (self.columCount - ) * self.minimumInteritemSpacing) / self.columCount; self.minimumInteritemSpacing = ; self.minimumLineSpacing = ; [self attribute:colWidth]; } - (void) attribute:(CGFloat) colWidth { NSInteger colCount[self.columCount]; CGFloat colHeight[self.columCount]; ; i<self.columCount; ++i) { colHeight[i] = ; colCount[i] = ; } // 定义总item高 CGFloat totoalItemHeight = ; // 定义一个可变数组,来存储 素有的属性值 NSMutableArray * arrayM = [NSMutableArray arrayWithCapacity:self.dataList.count]; // 计数 NSInteger index = ; // 遍历数组,计算相关的属性 for (Shop * shop in self.dataList) { // 1> 建立布局属性 NSIndexPath * indexPath = [NSIndexPath indexPathForRow:index inSection:]; index ++; UICollectionViewLayoutAttributes * attr = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; // 2.计算当前的列数 // 计算是第几列 NSInteger col = [self shortestCol:colHeight]; // 计算每一列的个数 colCount[col]++; // 3.计算frame CGFloat w = shop.w; CGFloat h = shop.h * colWidth / w; CGFloat x = self.sectionInset.left + (colWidth + self.minimumInteritemSpacing) * col; CGFloat y = colHeight[col] + self.minimumLineSpacing; // 累加,计算同一列下一个元素的高度 colHeight[col] += (h + self.minimumLineSpacing); attr.frame = CGRectMake(x, y, colWidth, h); // 4.计算总的高度 totoalItemHeight += h; // 5.添加到 itemsAttribute [arrayM addObject:attr]; } // 计算出最高的那一列 NSInteger highestCol = [self highestColL:colHeight]; // 设置 itemSize,使用总高度的平均值 self.itemSize = CGSizeMake(colWidth, (colHeight[highestCol]- colCount[highestCol] * self.minimumInteritemSpacing) / colCount[highestCol]); // 添加页脚属性 UICollectionViewLayoutAttributes * footer = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionFooter withIndexPath:[NSIndexPath indexPathForRow: inSection:]]; footer.frame = CGRectMake(, colHeight[highestCol], self.collectionView.bounds.size.width, ); [arrayM addObject:footer]; self.itemsAttribute = arrayM; } /// 返回所有 cell 的属性数组 - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect { return self.itemsAttribute; } /// 获得最少的那一列 /// /// @param colHeight 列高数组 /// /// @return 最少的列号 - (NSInteger) shortestCol:(CGFloat *)colHeight { CGFloat min = MAXFLOAT; CGFloat col = ; ; i<self.columCount; ++i) { if (colHeight[i] < min) { min = colHeight[i]; col = i; } } return col; } /// 获得最高的那一列 /// /// @param colHeight 列高数组 /// /// @return 最高的列号 - (NSInteger) highestColL:(CGFloat *)colHeight { CGFloat max = ; CGFloat col = ; ; i<self.columCount; ++i) { if(colHeight[i] > max) { max = colHeight[i]; col = i; } } return col; } #pragma mark - 懒加载 属性数组 - (NSMutableArray *)itemsAttribute { if (_itemsAttribute == nil) { _itemsAttribute = [NSMutableArray array]; } return _itemsAttribute; } @end
【iOS开发】collectionView 瀑布流实现的更多相关文章
- IOS开发之瀑布流照片墙实现
想必大家已经对互联网传统的照片布局方式司空见惯了,这种行列分明的布局虽然对用户来说简洁明了,但是长久的使用难免会产生审美疲劳.现在网上流行一种叫做“瀑布流”的照片布局样式,这种行与列参差不齐的状态着实 ...
- iOS之简单瀑布流的实现
iOS之简单瀑布流的实现 前言 超简单的瀑布流实现,这里说一下笔者的思路,详细代码在这里. 实现思路 collectionView能实现各中吊炸天的布局,其精髓就在于UICollectionVie ...
- iOS开发 - AVPlayer实现流音频边播边存
边播边下有三套左右实现思路,本文使用AVPlayer + AVURLAsset实现. 概述 1. AVPlayer简介 AVPlayer存在于AVFoundation中,可以播放视频和音频,可以理解为 ...
- iOS UITabView简写瀑布流
代码demo 一.tabViewCell,通过image的比例高算出cell 的高度 #import "TableViewCell.h" @implementation Table ...
- iOS开发之窥探UICollectionViewController(四) --一款功能强大的自定义瀑布流
在上一篇博客中<iOS开发之窥探UICollectionViewController(三) --使用UICollectionView自定义瀑布流>,自定义瀑布流的列数,Cell的外边距,C ...
- iOS开发之窥探UICollectionViewController(三) --使用UICollectionView自定义瀑布流
上篇博客的实例是自带的UICollectionViewDelegateFlowLayout布局基础上来做的Demo, 详情请看<iOS开发之窥探UICollectionViewControlle ...
- iOS开发笔记15:地图坐标转换那些事、block引用循环/weak–strong dance、UICollectionviewLayout及瀑布流、图层混合
1.地图坐标转换那些事 (1)投影坐标系与地理坐标系 地理坐标系使用三维球面来定义地球上的位置,单位即经纬度.但经纬度无法精确测量距离戒面积,也难以在平面地图戒计算机屏幕上显示数据.通过投影的方式可以 ...
- iOS开发:代码通用性以及其规范 第一篇(附带,自定义UITextView\进度条\双表显示\瀑布流 代码设计思路)
在iOS团队开发中,我见过一些人的代码,也修改过他们的代码.有的人的代码写的非常之规范.通用,几乎不用交流,就可以知道如何修改以及在它基础上扩展延生.有的人的代码写的很垃圾,一眼看过去,简直会怀疑自己 ...
- iOS开发-UICollectionView实现瀑布流
关于瀑布流的实现网上有很多种解法,自定义控件,TableView+ScrollView,UICollectionView是iOS6发布之后用于展示集合视图,算起来已经发布三年左右了,不过知识点是不变的 ...
随机推荐
- PMBOK 项目管理 九大知识领域和五大流程
PMI Project Management Institute.PMI 是世界上最大的非盈利机构,是项目管理领域的领导者.PMI制定项目管理行业标准,带领项目管理的研究并提供项目管理的培训,证书 ...
- C语言内存调试技巧—C语言最大难点揭秘
本文将带您了解一些良好的和内存相关的编码实践,以将内存错误保持在控制范围内.内存错误是 C 和 C++ 编程的祸根:它们很普遍,认识其严重性已有二十多年,但始终没有彻底解决,它们可能严重影响应用程序, ...
- PowerShell官方的MSDN
https://msdn.microsoft.com/en-us/powershell/mt173057.aspx 官方还咋github上放置了 扩展模块. 比如 web iis部署.sqlserv ...
- 【转】Gedit中文乱码
原文网址:http://wiki.ubuntu.org.cn/Gedit%E4%B8%AD%E6%96%87%E4%B9%B1%E7%A0%81#.E5.91.BD.E4.BB.A4.E6.96.B9 ...
- 【转】adb push&pull bug --- Permission denied----不错
原文网址:http://blog.csdn.net/hengkong_horse/article/details/8708076 问题背景: adb push E:\\rrr.txt /data/ ...
- 福建省队集训被虐记——DAY3
昨天没写--今天补上吧 一如既往的跪了 棋盘 [问题描述] 给出一个N*M的方格棋盘,每个格子里有一盏灯和一个开关,开始的时候,所有的灯都是关着的.用(x, y)表示第x行,y列的格子.(x, y)的 ...
- Sql Server 2005的1433端口打开和进行远程连接
参考地址:http://topic.csdn.net/u/20090828/16/e693935a-99b7-4090-a6bc-0123c91183eb.html 1.如何打开sql server ...
- 快速排序(Quick Sort)
快速排序是初学者比较难理解的几个算法之一,这里尽可简单化地讲解,希望能帮到大家. 快速排序基本步骤: 从数列中挑出一个元素,称为"基准"(pivot). 重新排序数列,所有元素比基 ...
- C语言漫谈(二) 图像显示 Windows和Linux
关于图像显示有很多库可以用,Windows下有GDI,GDI+,D3D等,Linux下有X Window和Wayland,此外还有OpenGL ,SDL等图形库以及各种GUI库. 了解最原始的方式,对 ...
- qt反走样(简选)
# -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' #qt反走样(简选) #概念 """ ...