iOS使用CollectionView实现瀑布流
来源:互联网 发布:升级win10用什么软件 编辑:程序博客网 时间:2024/05/14 17:35
瀑布流的原理
将屏幕等分成三列 然后将图片加载到每一列中,在加入到列之前,首先判断那一列的高度最低,然后把图片加到高度最低的那列中。
瀑布流设计思路分析
使用UICollectionView,采用自定义布局的方式,设置cell的排列规则 完成瀑布流。
- 自定义布局中,指定滚动方向,默认列数,行间距,列间距,以及指定cell的大小itemSize
- 创建一个数组columnMaxYs(记录当前每一列的最大Y值)
- 通过判断记录的最大Y值是否为最小的一列 计算item的X坐标 和Y坐标 并记录添加上的item那一列的最大Y坐标 设置item的frame属性
- 当我们的item进入复用池的时候,我们的界面展示的我们眼睛看到的以及我们想的,是和事实不相符的。 当我们向上滑动的时候你感觉 Y值在无线变大,但其实我们的Y值在最上方还是0。这里就需要用到prepareLayout方法。这个方法会在item出现在屏幕上之前反复执行。
- 在第一次加载的时候我们会计算所有的item的布局属性,但是当我们上下滑动的时候,还是需要重新计算这些布局属性,所以我们需要提供一个布局属性数组存放Cell的布局属性,避免必要的计算。
- 我们需要知道如何返回我们计算出来的item的布局属性,并且在那里计算合适,不会出现数据丢失的现行, layoutAttributesForElementsInRect:(返回所有元素的布局属性数组)。
- 这里需要设置Collection的滚动属性 ,就需要设置她的ContentSize 。没关系系统已经给出了这样的方法collectionViewContentSize
瀑布流的基本实现代码
#import <UIKit/UIKit.h>@interface ZQCollectionViewController : UICollectionViewController@end
#import "ZQCollectionViewController.h"#import "ZQCollectionViewCell.h"#import "ZQCollectionViewLayout.h"@interface ZQCollectionViewController (){ NSMutableArray *arr;}@end@implementation ZQCollectionViewControllerstatic NSString * const reuseIdentifier = @"Cell";- (void)viewDidLoad { [super viewDidLoad]; arr=[NSMutableArray array]; for (int i=0; i<49; i++) { NSString *string=[NSString stringWithFormat:@"%d.jpg",i%5+1]; [arr addObject:string]; } ZQCollectionViewLayout *layout=[[ZQCollectionViewLayout alloc]init]; layout.imageList=arr; self.collectionView.collectionViewLayout=layout; [self.collectionView registerNib:[UINib nibWithNibName:@"ZQCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:reuseIdentifier];}- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return 1;}- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return arr.count;}- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { ZQCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath]; cell.imgV.image =[UIImage imageNamed:arr[indexPath.row]]; cell.backgroundColor = [UIColor purpleColor]; return cell;}@end
#import <UIKit/UIKit.h>@interface ZQCollectionViewCell : UICollectionViewCell//注意这里是使用XIB绘制的@property (weak, nonatomic) IBOutlet UIImageView *imgV;@end
#import "ZQCollectionViewCell.h"@implementation ZQCollectionViewCell@end
#import <UIKit/UIKit.h>@interface ZQCollectionViewLayout : UICollectionViewLayout@property(nonatomic,copy)NSArray *imageList;@end
#import "ZQCollectionViewLayout.h"#define NewDefaultCollectionViewWidth self.collectionView.frame.size.width//static 只在当前作用域使用 const 不可修改的static const UIEdgeInsets NewDefaultInsets={10,10,10,10};//定义行列之间的间距static const CGFloat NewDefaultColumn=10;//定义默认的列数static int NewDeraultNumber=3;@interface ZQCollectionViewLayout ()//创建数组存放 Y值最大值 存放cell的布局属性@property(nonatomic,strong)NSMutableArray *columnArr;@property(nonatomic,strong)NSMutableArray *cellArr;@end@implementation ZQCollectionViewLayout- (NSMutableArray *)columnArr{ if (!_columnArr) { _columnArr=[NSMutableArray array]; } return _columnArr;}- (NSMutableArray *)cellArr{ if (!_cellArr) { _cellArr =[NSMutableArray array]; } return _cellArr;}- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{ UICollectionViewLayoutAttributes *attr=[UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; //布局属性刷新更改 //获取总的横向间距 CGFloat xMARGIN=NewDefaultInsets.left+NewDefaultInsets.right+(NewDeraultNumber-1)*NewDefaultColumn; CGFloat width=(NewDefaultCollectionViewWidth-xMARGIN)/NewDeraultNumber;#pragma mark -- 这里返回图片的高度 UIImage *image=[UIImage imageNamed:self.imageList[indexPath.row]]; CGFloat height=image.size.height *(width/image.size.width);#pragma mark -- 这里我们需要获取x坐标的值 如何获取 因为我们要做的是将需要展示的数组按顺序向下排列 而顺序就将后进来的插入到 最短的那一列 所以要获取这个x坐标我们就需要找出这个最小的y坐标才能确定 NSInteger sum=0;#pragma mark -- 下面这个遍历为什么要使用也是上面的原因 取出最大的y值 并获取对应的列数 其实columnArr只有三个元素 CGFloat sumMaxY=[self.columnArr[0] doubleValue]; for (int i=0; i<self.columnArr.count; i++) { CGFloat anyMaxY=[self.columnArr[i]doubleValue]; if (sumMaxY>anyMaxY) { sumMaxY=anyMaxY; sum=i; } } CGFloat x=NewDefaultInsets.left +sum*(width+NewDefaultColumn); CGFloat y=NewDefaultInsets.top+sumMaxY; attr.frame=CGRectMake(x, y, width, height); //更新数组,获取最大的Y 下一次比较时用到 记住每一次都会走下面这个方法 而这个方法 第一次的时候都是0 第二次的时候两个0 第三次的时候就不一样了 self.columnArr[sum]=@(CGRectGetMaxY(attr.frame)); return attr;}#pragma mark -- 这里下面的方法 是当我们向上或向下滑动item的时候 我们需要将我们的最大Y坐标重置 为什么呢 因为如果你继续使用最大Y坐标 它还是向下排列- (void)prepareLayout{ [super prepareLayout]; //设置cell的最大Y值 [self.columnArr removeAllObjects]; for (int i=0; i<NewDeraultNumber; i++) { //这里使用下面的方法是给最大值一个初始值 [self.columnArr addObject:@(NewDefaultInsets.top)]; } //设置cell的布局属性 这里的self.layoutAttributesForItemAtIndexPath 是本类的一个属性 通过对应的indexPath我们可以拿到对应的item的布局属性 然后存储起来 [self.cellArr removeAllObjects]; NSInteger count=[self.collectionView numberOfItemsInSection:0]; for (int i=0; i<count; i++) { NSIndexPath *indexPath=[NSIndexPath indexPathForItem:i inSection:0]; UICollectionViewLayoutAttributes *attrs=[self layoutAttributesForItemAtIndexPath:indexPath]; [self.cellArr addObject:attrs]; }}#pragma mark -- 设置collectionView的范围 contentSize- (CGSize)collectionViewContentSize{ CGFloat sumMaxY=[self.columnArr[0] doubleValue]; for (int i=0; i<self.columnArr.count; i++) { CGFloat anyMaxY=[self.columnArr[i]doubleValue]; if (sumMaxY>anyMaxY) { sumMaxY=anyMaxY; } } //这里返回的横坐标是什么都可以 return CGSizeMake(0, sumMaxY);}- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{ //在里我们将我们存储起来的item布局属性交付给cell return self.cellArr;}@end
0 0
- iOS使用CollectionView实现瀑布流
- iOS collectionView实现瀑布流
- CollectionView实现瀑布流
- collectionView实现瀑布流
- 瀑布流 collectionView实现
- collectionView实现瀑布流
- iOS-CollectionView 瀑布流视图
- iOS 【使用CollectionView瀑布流布局】
- iOS-CollectionView瀑布流框架搭建
- CollectionView实现瀑布流(swift)
- CollectionView和layout的使用,瀑布流
- iOS 使用UICollectionView实现瀑布流
- 整理 collectionView 瀑布流 布局
- iOS 使用collectionView实现无线轮播
- iOS 瀑布流实现
- iOS collectionView使用
- iOS CollectionView简单使用
- collectionView的使用iOS
- Intel Edison 装Debian系统
- 背包(1)
- C# Lock关键字
- Android Studio 设置内存大小及原理
- 史上最详细的Android Studio系列教程三--快捷键
- iOS使用CollectionView实现瀑布流
- MyEclipse连接Oracle错误:ORA-00604和ORA-12705
- 背包2
- adb无法使用,提示error: unknown host service的解决办法
- template模板在Windows和Linux下的不同用法
- 将博客搬至CSDN
- Cloud39E的UART1串口使用问题
- 使用七牛上传图片并加水印
- 奇偶校验