这是个人记录学习 ,想要详细了解的 。请参考文章:https://www.jianshu.com/p/2b9a73aefe28 这里面说的很详细。感谢大佬
1.首先自定义UICollectionViewFlowLayout
MyCustomFlowLayout.h 文件
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface MyCustomFlowLayout : UICollectionViewFlowLayout
@property (nonatomic,assign) CGFloat itemWith;
/**
瀑布流布局方法
@param itemWidth item 的宽度
@param itemHeightArray item 的高度数组
*/
- (void)flowLayoutWithItemWidth:(CGFloat)itemWidth itemHeightArray:(NSArray<NSNumber *> *)itemHeightArray;
@end
NS_ASSUME_NONNULL_END
MyCustomFlowLayout.m 文件
#import "MyCustomFlowLayout.h"
@interface MyCustomFlowLayout()
/**
item 的高度数组
*/
@property (nonatomic, copy) NSArray<NSNumber *> *arrItemHeight;
/**
cell 布局属性集
*/
@property (nonatomic, strong) NSArray<UICollectionViewLayoutAttributes *> *arrAttributes;
@end
@implementation MyCustomFlowLayout
- (void)flowLayoutWithItemWidth:(CGFloat)itemWidth itemHeightArray:(NSArray<NSNumber *> *)itemHeightArray {
self.itemSize = CGSizeMake(itemWidth, 0);
self.arrItemHeight = itemHeightArray;
[self.collectionView reloadData];
}
-(void)setItemWith:(CGFloat)itemWith{
_itemWith = itemWith;
}
- (void)prepareLayout {
[super prepareLayout];
// item 数量为零不做处理
if ([self.arrItemHeight count] == 0) {
return;
}
// 计算一行可以放多少个项
NSInteger nItemInRow = (self.collectionViewContentSize.width - self.sectionInset.left - self.sectionInset.right + self.minimumInteritemSpacing) / (self.itemSize.width + self.minimumInteritemSpacing);
// 对列的长度进行累计
NSMutableArray *arrmColumnLength = [NSMutableArray arrayWithCapacity:100];
for (NSInteger i = 0; i < nItemInRow; i++) {
[arrmColumnLength addObject:@0];
}
NSMutableArray *arrmTemp = [NSMutableArray arrayWithCapacity:100];
// 遍历设置每一个item的布局
for (NSInteger i = 0; i < [self.arrItemHeight count]; i++) {
// 设置每个item的位置等相关属性
NSIndexPath *index = [NSIndexPath indexPathForItem:i inSection:0];
// 创建每一个布局属性类,通过indexPath来创建
UICollectionViewLayoutAttributes *attris = [self layoutAttributesForItemAtIndexPath:index];
CGRect recFrame = attris.frame;
// 有数组得到的高度
recFrame.size.height = [self.arrItemHeight[i] doubleValue];
// 最短列序号
NSInteger nNumShort = 0;
// 最短的长度
CGFloat fShortLength = [arrmColumnLength[0] doubleValue];
// 比较是否存在更短的列
for (int i = 1; i < [arrmColumnLength count]; i++) {
CGFloat fLength = [arrmColumnLength[i] doubleValue];
if (fLength < fShortLength) {
nNumShort = i;
fShortLength = fLength;
}
}
// 插入到最短的列中
recFrame.origin.x = self.sectionInset.left + (self.itemSize.width + self.minimumInteritemSpacing) * nNumShort;
recFrame.origin.y = fShortLength + self.minimumLineSpacing;
// 更新列的累计长度
arrmColumnLength[nNumShort] = [NSNumber numberWithDouble:CGRectGetMaxY(recFrame)];
// 更新布局
attris.frame = recFrame;
[arrmTemp addObject:attris];
}
self.arrAttributes = arrmTemp;
// 因为使用了瀑布流布局使得滚动范围是根据 item 的大小和个数决定的,所以以最长的列为基准,将高度平均到每一个 cell 中
// 最长列序号
NSInteger nNumLong = 0;
// 最长的长度
CGFloat fLongLength = [arrmColumnLength[0] doubleValue];
// 比较是否存在更短的列
for (int i = 1; i < [arrmColumnLength count]; i++) {
CGFloat fLength = [arrmColumnLength[i] doubleValue];
if (fLength > fLongLength) {
nNumLong = i;
fLongLength = fLength;
}
}
// 在大小一样的情况下,有多少行
NSInteger nRows = ([self.arrItemHeight count] + nItemInRow - 1) / nItemInRow;
self.itemSize = CGSizeMake(self.itemSize.width, (fLongLength + self.minimumLineSpacing) / nRows - self.minimumLineSpacing);
}
// 返回所有的 cell 布局数组
-(NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect {
return self.arrAttributes;
}
@end
- 调用方法
#define kScreenWidth [UIScreen mainScreen].bounds.size.width
#define kScreenHeight [UIScreen mainScreen].bounds.size.height
#import "WalltViewController.h"
#import "MyCustomFlowLayout.h"
#import "Masonry.h"
@interface WalltViewController ()<UICollectionViewDelegate,UICollectionViewDataSource>
@property (nonatomic , strong) UICollectionView *collection;
@property (nonatomic , strong) MyCustomFlowLayout *myLayout;
@property (nonatomic , strong) NSMutableArray *arrmHeight;
@end
static NSString *cellId = @"custom_cell";
@implementation WalltViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.myLayout = [[MyCustomFlowLayout alloc] init];
// 以最小间距为10计算间距
// 每行可放多少 cell
self.myLayout.itemWith = 150;
NSInteger nCountCell = (kScreenWidth - 10) / (self.myLayout.itemWith + 10);
// 平均后的间距
CGFloat fSpacing = (kScreenWidth - self.myLayout.itemWith * nCountCell) / (nCountCell + 1);
self.myLayout.minimumInteritemSpacing = fSpacing;
self.myLayout.minimumLineSpacing = fSpacing;
self.myLayout.sectionInset = UIEdgeInsetsMake(fSpacing, fSpacing, fSpacing, fSpacing);
// 创建随机高度的数组
_arrmHeight = [NSMutableArray array];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
for (int j=0; j<40; j++) {
if (j % 4 == 0) {
[_arrmHeight addObject:[NSNumber numberWithFloat:190.0]];
}else if (j % 4 == 1){
[_arrmHeight addObject:[NSNumber numberWithFloat:260.0]];
}else if (j % 4 == 2){
[_arrmHeight addObject:[NSNumber numberWithFloat:260.0]];
}else if (j % 4 == 3){
[_arrmHeight addObject:[NSNumber numberWithFloat:190.0]];
}
}
[self.myLayout flowLayoutWithItemWidth:150 itemHeightArray:_arrmHeight];
});
_collection = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 64, kScreenWidth, kScreenHeight - 64) collectionViewLayout:self.myLayout];
_collection.backgroundColor = [UIColor whiteColor];
_collection.delegate = self;
_collection.dataSource = self;
[self.view addSubview:_collection];
// 注册 cell
[_collection registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:cellId];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellId forIndexPath:indexPath];
for (UIView *view in cell.contentView.subviews) {
[view removeFromSuperview];
}
CGFloat height = [_arrmHeight[indexPath.item] floatValue]-70;
UIImageView *imageView = [[UIImageView alloc] init];
imageView.frame = CGRectMake(0, 0, 150, height);
imageView.backgroundColor = [UIColor colorWithRed:arc4random_uniform(256)/255.0 green:arc4random_uniform(256)/255.0 blue:arc4random_uniform(256)/255.0 alpha:1];
[cell.contentView addSubview:imageView];
UILabel *label = [[UILabel alloc] init];
label.text = @"拟把疏狂图一醉,对酒当歌,强乐还无味,衣带渐宽终不悔,为伊消得人憔悴";
label.textColor = [UIColor colorWithRed:arc4random_uniform(256)/255.0 green:arc4random_uniform(256)/255.0 blue:arc4random_uniform(256)/255.0 alpha:1];
label.font = [UIFont systemFontOfSize:16];
label.textAlignment = NSTextAlignmentLeft;
[cell.contentView addSubview:label];
[label mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(cell.contentView);
make.right.mas_equalTo(cell.contentView);
make.top.equalTo(imageView.mas_bottom).offset(5);
make.height.mas_equalTo(20);
}];
UIImageView *iconImageV = [[UIImageView alloc] init];
iconImageV.image = [UIImage imageNamed:@"h7"];
[cell.contentView addSubview:iconImageV];
[iconImageV mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(cell.contentView);
make.top.equalTo(label.mas_bottom).offset(5);
make.size.mas_equalTo(CGSizeMake(40, 40));
}];
iconImageV.layer.cornerRadius = 20;
iconImageV.layer.masksToBounds = YES;
UILabel *nameLabel = [[UILabel alloc] init];
nameLabel.text = @"青平乐";
nameLabel.textColor = [UIColor colorWithRed:arc4random_uniform(256)/255.0 green:arc4random_uniform(256)/255.0 blue:arc4random_uniform(256)/255.0 alpha:1];
nameLabel.font = [UIFont systemFontOfSize:13];
nameLabel.textAlignment = NSTextAlignmentCenter;
[cell.contentView addSubview:nameLabel];
[nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(iconImageV.mas_right).offset(20);
make.centerY.mas_equalTo(iconImageV);
make.width.mas_equalTo(40);
make.height.mas_equalTo(20);
}];
return cell;
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return _arrmHeight.count;
}
网友评论