ios UI基础瀑布流 顾名思义是将界面以瀑布流水般的展现出来,使用瀑布流,首先对数据进行懒加载,传入数据后,使用UIcollectionView控件在main.storyboard里进行简单的布局

![collectionView的item布局]

collectionView已经设置的和屏幕等宽等高了

然后使用collectionViewDataSource代理  从flowLayOut连一根线到View controller,然后遵循协议,实现代理方法

-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView

//返回组

-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section

//返回item

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

//创建UICollectionViewCell

注意在这里我们使用的是原型cell,所以不会出现cell不存在的情况,所以不用担心cell重用的问题,因为系统一加载数据就会创建一个cell,接下来我们要获取cell中的imageView和Label,使用[cell viewWithTag:]方法,这个方法返回值是一个UIview,我们要用一个UIView来接收,所有的控件都继承自UIView,因此image用UIImageView来接收,Label用UI label来接收,(是否碰到报错的情况呢?

```_***dequeueReusableViewOfKind:withIdentifier:forIndexPath:viewCategory:],*** /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3505.16/UICollectionView.m:3600

*2016-03-11 11:01:47.920 瀑布流[943:32280] Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'could not dequeue a view of kind: UICollectionElementKindCell with identifier haha - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'

First throw call stack```

这个错误很简单,想想自己是否将main.storyboard里的UICollectionViewCell中的identifier和你.m中定义的标识是否一致)

接下来运行看一下数据有没有加载到,背景是黑色的很奇怪吗?UICollectionView控件默认的背景就是黑色,不用担心

****

界面搭建完了发现布局不是我们想要的效果,所以,我们将要自定义一个layout,让它继承自UICollectionViewFlowLayOut(为什么不继承自UICollectionViewLayOut呢?是因为UICollectionViewFlowLayOut里的属性UICollectionViewLayOut里面没有)既然是自定义的layout,那么一上来就有6个方法,这是系统的方法不必纠结

-(void)prepareLayout

//在layout运行加载前调用的方法

-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath

//根据indexPath获取当前控件的属性

-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect

//返回可视区域的控件属性,程序一运行我们就能看到的

-(BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds

//当界面改变的时候,需要重新更新界面的bounds

-(CGSize)collectionViewContentSize

//

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

//当界面滚动的时候调用的方法,需要做动画处理的方法

写完这6个方法后,

****

接下来  **框架分析**

第一步:就开始分析首先我们考虑 程序一运行我们所看到的界面是改变后的界面,那么在这6个方法里有一个方法是返回可视区域内的控件属性-(NSArray<UICollectionViewLayoutAttributes *>方法,在这里返回的是改变后的item的集合,也就是说在程序运行之前一定调用了一个方法改变之前的item

第二步:第一步中程序运行,在cmd+R的时候模拟器就给我们展现出了这样瀑布流的界面,在layout加载前就调用这个方法就是-(void)prepareLayout方法,在这里首先我们应该遍历每一个原先的item,然后调用根据indexPath获得当前item属性的方法得到改变后的item添加到一个可变数组中,(在这里,遍历原先的item 需要获取原先的collectionView里的item的数量,indexpath索引值通过NSindexPath方法进行获取

第三步:既然要改变item的属性那么看看这6个方法,我们发现有一个根据indexPath获得当前item的属性方法-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath,我们肯定是要在这个方法里做文章,首先想要改变item的属性,那就要先获取原来的item,然后通过计获取的新的item的坐标和尺寸,将原来的item的frame改变。

****

算法分析

第一步:先计算控件的尺寸:

item的宽 = (屏幕的宽度也就是CollectionView的宽度-item之间的最小的间隙*(每一行的item数量-1)-左间距-右间距)/每一行的item的数量

在这里每一行的item的数量我们是不知道的,这个希望别人自己去定义,所以我们希望别人自己定义,那就不能把这个属性定义在.m文件里,所以我们在.h文件中定义这个属性,不排除有得人乱定义,将每一行的item设置为0的情况,所以在.m文件里需要重写一下这个属性的get方法。(如果为0则返回3)

item的高 = 高/宽*宽

(宽在第一步里是已知的,高/宽的比率需要写一个方法来实现)我们在layout里是无法直接知道控件的宽和高的,所以自己的事自己不能直接去做,那么我们就设置一个代理,代理三部曲就不多说了,在这里判断一下什么时候用@optional和@required,还有dataSource和Delegate  ,首先看这个方法会不会影响程序运行,有影响则用dataSource,否则用Delegate,必须实现的话就用required否则用optional,套路就不说了,这里说几个注意点,将这个代理在ViewController中用的时候在获取item宽高数据的时候我们发现需要一个indexPath的索引值,我们看回去在FlowLayOut中计算item尺寸的方法里我们有indexPath,所以需要传一个indexPath的索引值,随之代理中也要传一个IndexPath的索引值,在返回item宽高比率的时候别忘记宽高是NSinteger类型,而代理中返回的是CGFloat类型的,所以要进行强转。

根据九宫格算法

item的X = 左边距+当前item的列数*(item的宽+item之间的间隙)

这里唯一不知道的变量是当前item的列数,我们需要去定义一个当前列(*为什么不用indexPath.item(当前控件cell是处于第几组的第几个item)%这一行的控件的个数,虽然也可以获得当前列,但是它使控件的排列方式是第一行排列完紧接着排列第二行,很死板,这样会导致有可能最后的瀑布流看起来很难看*),然后去获取最小的Y值的当前列,然后排列的时候一行排完后下一行按照上一行最小的Y进行排列,变得很灵活,不管出现什么情况最后的图案也是比较好看的,说到这里应该发现我们应该先去计算Y的值,这样才能获取到最小Y的值

定义一个数组去挨个存放每一个控件的Y值,做更新CGRectMaxY得到每一个控件Y的最大值存放在数组中,然后遍历这个存放Y的最大值的数组,定义一个Y值,重写它的get方法,获取到存放最大Y值数组的当前的Y值,然后用定义的Y与获取到的当前的Y值做比较将最小的那个赋值给定义的Y,就得到我们的最小Y ,同时也能得到我们的当前列

item的Y = 最小的Y+列间距

在这里别忘记要更新存放在数组中的最大的Y值!!!

最后设置滚动范围

容易遇到的不报错Bug:1.定义的数组没有进行初始化操作 2.遍历的时候该遍历谁要明确3.更新Y值的时候,注意将CGFloat转换成NSString类型 4.实现代理方法中记得将NSInteger强转。

iOS基础UI瀑布流界面简单搭建相关推荐

  1. iOS基础——UI控件之UIAlertController、UINavigationController、Segue、SVProgressHUD

    iOS基础--UI控件之UIAlertController.UINavigationController.Segue 一.UIAlertController 1.普通对话框 -(void)update ...

  2. RHEL4- SAMBA服务(四)在x-window下图形界面简单搭建samba服务器

    RHEL4- SAMBA服务(四)在x-window下图形界面简单搭建samba服务器       在<RHEL4- SAMBA服务(一)samba服务的安装与启动>中我讲了如何安装和启动 ...

  3. iOS 美丽说瀑布流界面纯AutoLayout光速布局

    最近在Github上看到三个库,分别是 GSKStretchyHeaderView,CHTCollectionViewWaterfallLayout ,JZNavigationExtension, 其 ...

  4. iOS开发之瀑布流照片墙实现

    想必大家已经对互联网传统的照片布局方式司空见惯了,这种行列分明的布局虽然对用户来说简洁明了,但是长久的使用难免会产生审美疲劳.现在网上流行一种叫做"瀑布流"的照片布局样式,这种行与 ...

  5. iOS UICollectionView实现瀑布流(3)

    前面两篇Blog简单的介绍了UICollection的基本使用并实现了类似Android的Gallery效果,这篇文章使用UICollection来实现瀑布流效果,代码主要是在极客学院Carol老师的 ...

  6. 关于瀑布流的简单实现

    实现瀑布流,首先需要数据,这里我们制作一批假数据 安装json-server npm install json-server 使用mock.js随机生成批量数据 npm init npm instal ...

  7. iOS开发UI篇—xib的简单使用

    一.简单介绍 xib和storyboard的比较,一个轻量级一个重量级. 共同点: 都用来描述软件界面 都用Interface Builder工具来编辑 不同点: Xib是轻量级的,用来描述局部的UI ...

  8. ios UICollectionViewLayout 横向瀑布流

    2019独角兽企业重金招聘Python工程师标准>>> 效果: 截图没有显示出抖动效果 // // mierLayout.m // diaojiba // // Created by ...

  9. Hexo Next 博客添加相册瀑布流

    原文:https://rebootcat.com/2020/09/19/nextphotowall/ 前言 一直没有时间来整理下博客搭建的一些事情,现在补上一篇,给 Hexo Next 博客添加一个相 ...

最新文章

  1. mongodb数据库显示obj_MongoDB基础(三)—基本操作及管理 | leon的博客
  2. qml mousearea 点击其他地方_Qml 快速使用
  3. Ane技术大全 - Devil程序员
  4. HttpClient通过Post方式发送Json数据
  5. 人类繁荣的数学:数学的哈欠
  6. ApacheCN 交流社区一周热点 2019.4 wk1
  7. python循环结构高一信息技术有限公司_Python之循环结构
  8. one hot 编码的实现
  9. pythonxml库_Python XML操作
  10. 旧文重现,10种职场经典寓言
  11. TableViewCell的折展(Masonry)
  12. floppy计算机专业术语,计算机专业术语解释
  13. USACO3.4 “破锣摇滚”乐队 Raucous Rockers - DP
  14. 电脑 变速 java游戏_极品飞车-变速FX版
  15. python 网络拓扑图_python 网络拓扑图
  16. 135编辑器的html,百度编辑器 整合135编辑器
  17. 十个要点让你的渲染更好
  18. 《大数据机器学习实践探索》 ---- 大数据机器学习:spark mlib 库【简介 与 架构初探】
  19. 「合作共赢」泛微eteams云OA联手容联七陌 深耕SaaS协同软件市场
  20. Spring—xml和注解

热门文章

  1. matplotlib更改窗口图标
  2. Transaction Processing on Modern Hardware 读书笔记
  3. bat启动cmd,超级管理员
  4. MSDN经典案例分析--PetShop
  5. 机械臂操作运动传送带上的物体
  6. 2022-2028全球钢材防火涂料行业调研及趋势分析报告
  7. ejb2.1中ejbQL的缺点,权且作为笔记
  8. 英音与美音的区别【转】
  9. Google AudioSet-谷歌语音数据集如何解析
  10. TCP/IP协议栈 头部参数