其实对于瀑布流的实现原理并不是多难,像常见的应用一般都是把屏幕分为等宽的两列或三列,在将图片放入每一列,不同的图片判断出不同的高度,在加入列之前,判断哪一列的高度最低,将图片插在那一列的下面。
以前经常使用的是用UITableView或UIScrollView来实现瀑布流
首先拿到数据,如果要做成3列,就用三个UItableview,宽度平均,高度动态,页面高度取UItableview中最高的;三个UItableview初始化的时候用到tag,然后 showsVerticalScrollIndicator和scrollEnabled设为no,separatorStyle设为 UITableViewCellSeparatorStyleNone,添加到UIview中。
使用UIScrollView的原理:核心是Cell的重用机制,根据图片的大小和相关信息,来判断图片所在位置,和图片高度;
个人更喜欢现在比较流行的使用UICollectionView来实现瀑布流的布局
使用UICollectionView来实现通常是来通过创建一个布局类继承UICollectionViewFlowLayout,用这个自定义的布局类来控制图片大小事项瀑布流。
在网上找到一个豆瓣相册的开源APP,写的不错,就以此来分析UICollectionView实现瀑布流的过程
首先在StoryBoard里面新建一个UICollectionViewController或者在UIViewController里添加一个UICollectionView,然后对应视图新建相对应得Controller文件设置关联映射;
然后新建一个类DAWaterfallLayout继承至UICollectionViewFlowLayout(FlowLayout是UICollectionViewLayout的实例,自定义Layout不支持UICollectionViewLayout,支持UICollectionViewFlowLayout),然后将自定义WaterfallLayout填充到StoryBoard里UICollectionView的Layout属性里;
接着就是来实现DAWaterfallLayout类,首先考虑项目的数据情况,列出所需要的元素并作出声明;
@interface DAWaterfallLayout ()//瀑布流布局声明
@property (nonatomic, assign) NSInteger itemCount;//项目数
@property (nonatomic, strong) NSMutableArray *columnHeights; //每一列高度
@property (nonatomic, assign) NSInteger allItems;//总项目数
@property (nonatomic, strong) NSMutableArray *allItemAttributes;//总项目属性
@end
@implementation DAWaterfallLayout{ //瀑布流布局声明
CGFloat nextStyleY; // 下一个风格的Y值
NSUInteger countForStyle0; // 风格_0数
NSUInteger countForStyle1; // 风格_1数
NSUInteger countForStyle2; // 风格_2数
NSUInteger countForStyle3; // 风格_3数
NSUInteger style; //添加新的风格
BOOL needNewStyle; //添加新的风格
BOOL _hasConfigNameAndDescribeLayout;//是否包含配置名描述的布局
}
拓展的布局类中封装了对瀑布流的实现,在调用时需要对创建的元素初始化,声明出一个清除布局属性的方法,用于创建layout对象时调用
#import <UIKit/UIKit.h>
@interface DAWaterfallLayout : UICollectionViewFlowLayout{
CGFloat _contentSizeHeight;
}
- (void)clearLayoutAttributes;
@end
- (void)clearLayoutAttributes{ //清除布局属性
_hasConfigNameAndDescribeLayout = NO; //无包含配置名描述的布局
needNewStyle = YES; //需要新的风格
countForStyle0 = 0; // 风格_0数为0
countForStyle1 = 0; // 风格_1数为0
countForStyle2 = 0; // 风格_2数为0
countForStyle3 = 0; // 风格_3数为0
style = 0; //风格数为0
nextStyleY = 65; // 下一个风格的Y值为65
_allItems=[[self collectionView] numberOfItemsInSection:0];
NSLog(@"总项目数为%d",_allItems);
_allItemAttributes = [NSMutableArray arrayWithCapacity:_allItems];
//总项目属性(可变数组类型)
}
复写prepareLayout方法进行视图的创建和布局,拿到数据对数据进行判断,设置标题和图片的风格,默认的风格有4种分别是左一右一,左大一右小二,左小二右大一,左二右二;这种瀑布流相比于平常的等宽不等高的瀑布流多进行了宽度的计算。对内容的数量分配不同的风格数来在屏幕上显示。
其中也对取到的UIIn