详解IOS中如何实现瀑布流效果
移动互联网让越来越多人使用,然而很多程序的展现让大家眼前一亮,当然它们的实现方式也是不一样的,一起随爱站技术频道小编来了解详解IOS中如何实现瀑布流效果吧!
首先是效果演示

特点:可以自由设置瀑布流的总列数(效果演示为2列)
虽然iphone手机的系统相册没有使用这种布局效果,瀑布流依然是一种很常见的布局方式!!!下面来详细介绍如何实现这种布局.
首先使用的类是UICollectionView
我们要做的是自定义UICollectionViewCell和UICollectionViewLayout
1、自定义UICollectionViewCell类,只需要一个UIImageView即可,frame占满整个cell.
2、重点是自定义UICollectionViewLayout,注意一定要继承于UICollectionViewLayout,千万别继承于UIColletionViewFlowLayout.
3、另外还需要计算图片高度.
为什么要自定义UICollectionViewLayout ?
因为我们需要设置每个item的高度以及位置, 注意这里是位置, 我们真的会设置每个item的位置的相信我!!!自定义UICollectionViewLayout必须要重写三个协议方法,后面会讲到.
为什么要计算图片高度 ?
因为图片宽度固定,所以需要按照图片的比例来计算高度,使图片等比例显示.这样的好处是,妈妈再也不用担心我的照片被拉伸的奇形怪状了...而且还需要用图片的高度来计算整个CollectionView的contentSize...打完收工!!!
主菜来了!!!
以下内容均在自定义的CustomCollectionViewLayout类里边
//自定义UICollectionViewLayout必须要重写的三个协议方法 //1.计算每个item的大小和位置 - (void)prepareLayout; //2.返回每个item的布局属性 - (nullable NSArray<__kindof uicollectionviewlayoutattributes> *)layoutAttributesForElementsInRect:(CGRect)rect; //3.返回collectionView的总高度 - (CGSize)collectionViewContentSize;
可以看到第三个方法使用了Nullability和泛型,系统的方法都添加了iOS 9新特性。
通过上边的三个方法名我们可以大致了解需要去做什么.说一下第二个方法,需要返回一个数组,数组存放布局属性(UICollectionViewLayoutAttributes)对象.那么我们需要写一个属性数组(attributesArray),将布局属性放入这个属性数组并返回.

还需要什么呢 ?看了文章开头的朋友应该注意到了,设置瀑布流的列数当然得有个属性(numberOfColumns)来表示列数.
请注意,因为要在外部设置列数,所以这个属性需要写在自定义类的.h文件中
另外为了方便,定义一个属性(itemWidth)来表示item的宽度
再定义一个属性(contentHeight)来表示整个collectionView的contenView的高度

首先是初始化,并没有什么问题
- (instancetype)init {
self = [super init];
if (self) {
_attributesArray = [NSMutableArray array];
// 默认值设置为2列
_numberOfColumns = 2;
_contentHeight = 0.0f;
_cellMargin = 5.0f;/**
然后是getter方法,只需要使用点语法即可得到itemWidth的值(因为它就是固定的)
- (CGFloat)itemWidth {
//所有边距的和.两列时有三个边距, 三列时有四个边距,逻辑强大就是好...
CGFloat allMargin = (_numberOfColumns + 1) * _cellMargin;
//除去边界之后的总宽度
CGFloat noMarginWidth = CGRectGetWidth(self.collectionView.bounds) - allMargin;
//出去边距的总宽度除以列数得到每一列的宽度(也就是itemWidth)
return noMarginWidth / _numberOfColumns;
}
---接下来是难点---
必须重写的第一个方法
- (void)prepareLayout {
// 定义变量记录高度最小的列,初始为第0列高度最小.
#pragma mark - 注意这个是从0开始算的啊!!!
NSInteger shortestColumn = 0;
#pragma mark - 注意这个是从0开始算的啊!!!
// 存储每一列的总高度.因为添加图片的列高度会变,所以需要定义一个数组来记录列的总高度.
NSMutableArray *columnHeightArray = [NSMutableArray array];
// 设置列的初始高度为边距的高度,没毛病!!!
for (int i = 0; i height) {
//第i列高度(height)最低时,高度最低的列(shortestColumn)当然就是第i列了
shortestColumn = i;
}
}
}
// 思考下只使用上边的代码会出现什么问题
// 并不能影响心情,请不要恐慌...
// 提示:这个方法会被多次调用,数组
}
---难点已经结束---
没有理解的朋友请重点看上边的难点方法.
必须重写的第二个方法
// 2.返回的是, 每个item对应的布局属性 - (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect { return _attributesArray; }
必须重写的第三个方法
// 3.返回CollectionView的滚动范围
- (CGSize)collectionViewContentSize {
return CGSizeMake(0, _contentHeight);
}
ViewController里边关于CollectionView的创建和协议方法就没什么好说的了.
看下自定义类CustomCollectionViewLayout的创建以及属性的赋值情况:
CustomCollectionViewLayout *layout = [[CustomCollectionViewLayout alloc] init]; layout.numberOfColumns = 2;/**
再看下协议方法的实现部分(在ViewController.m中实现)
- (CGFloat)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
width:(CGFloat)width
heightForItemAtIndexPath:(nonnull NSIndexPath *)indexPath {
UIImage *image = _imagesArray[indexPath.row];
// 根据传过来的宽度来设置一个合适的矩形, 高度设为CGFLOAT_MAX表示以宽度来计算高度
CGRect boundingRect = CGRectMake(0, 0, width, CGFLOAT_MAX);
// 通过系统函数来得到最终的矩形,需要引入头文件
// #import
CGRect imageCurrentRect = AVMakeRectWithAspectRatioInsideRect(image.size, boundingRect);
return imageCurrentRect.size.height;
}
上述是爱站技术频道小编介绍的详解IOS中如何实现瀑布流效果,感兴趣的朋友也可以自己尝试,希望小编的介绍能帮到您。
下一篇:iOS实现侧滑栏效果
