您的位置:首页 > 编程语言

【代码笔记】自定义布局实现瀑布流

2016-03-03 00:23 459 查看
利用collectionView实现瀑布流的效果,

文件目录如下



动画效果图如下:



//ViewController文件

#import "ViewController.h"
#import "LYWaterFlowLayout.h"
#import "LYWaterCell.h"
#import "LYShopModel.h"

@interface ViewController ()<UICollectionViewDataSource>
@property(nonatomic,strong)NSArray *shops;

@end

@implementation ViewController
static NSString *ID = @"water";

- (NSArray *)shops{

if (_shops == nil) {
//        1.读取文件
NSString *path =  [[NSBundle mainBundle ]pathForResource:@"1.plist" ofType:nil];
NSArray *dictArray =  [NSArray arrayWithContentsOfFile:path];
//        2.字典转模型
NSMutableArray *tempArray = [NSMutableArray array];
for (NSDictionary *dict in dictArray) {
LYShopModel *shop = [LYShopModel shopWithDict:dict];
[tempArray addObject:shop];

}
_shops = tempArray;

}
return _shops;
}

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//    0.自定义布局
LYWaterFlowLayout *waterFlowLayout = [[LYWaterFlowLayout alloc]init];
//    0.1.传递外界数组到内部
waterFlowLayout.shops = self.shops;

//    1.创建collectionView
UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height) collectionViewLayout:waterFlowLayout];
//    2.设置数据源
collectionView.dataSource = self;
////    3.设置代理
//    collectionView.delegate = self;

//    3.添加
[self.view addSubview:collectionView];
//    4.注册cell
[collectionView registerNib:[UINib nibWithNibName:@"LYWaterCell" bundle:nil] forCellWithReuseIdentifier:ID];

}

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{

return  1;

}

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

return self.shops.count;
}

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

//    1.创建cell

LYWaterCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
//    2.赋值
//
//    cell.backgroundColor = [UIColor redColor];
//    2.1获取模型
LYShopModel *shop = self.shops[indexPath.item];
cell.shop = shop;

cell.indexPath=indexPath;
//   3.返回cell
return cell;

}

@end


//LYWaterCell文件
#import <UIKit/UIKit.h>
@class LYShopModel;

@interface LYWaterCell : UICollectionViewCell
@property(nonatomic,strong)LYShopModel *shop;

@property(nonatomic,strong)NSIndexPath *indexPath;

@end

#import "LYWaterCell.h"
#import "LYShopModel.h"

@interface LYWaterCell()

@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@property (weak, nonatomic) IBOutlet UILabel *priceLabel;

@end
@implementation LYWaterCell
- (void)setShop:(LYShopModel *)shop{

_shop = shop;

self.iconView.image = [UIImage imageNamed:shop.icon];
//self.priceLabel.text = shop.price;

}
-(void)setIndexPath:(NSIndexPath *)indexPath{

_indexPath = indexPath;
self.priceLabel.text = self.shop.price;

}

@end


//LYWaterFlowLayout文件
#import <UIKit/UIKit.h>

@interface LYWaterFlowLayout : UICollectionViewFlowLayout

@property(nonatomic,strong)NSArray *shops;

@end

int const column = 3;
#import "LYWaterFlowLayout.h"
#import "LYShopModel.h"

@interface LYWaterFlowLayout()

@property(nonatomic,strong)NSMutableArray *maxYs;
@end

@implementation LYWaterFlowLayout
- (NSMutableArray *)maxYs{

if (_maxYs == nil) {
_maxYs = [NSMutableArray array];
NSLog(@"%@",_maxYs);

}

return _maxYs;
}

/**
*  用来设置每一个对应位置的item属性
*
*  @param indexPath 用来确定每一item具体位置
*
*  @return 用来设置每一个item的属性
*/
-(UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{
//NSLog(@"调用了layoutAttributesForItemAtIndexPath");
//    1.确定上左下右间距

UIEdgeInsets edge = UIEdgeInsetsMake(10, 10, 10, 10);
//     2.确定宽度
//        2.1确定列数

//        2.2确定行间距和列间距
CGFloat rowMargin = 10;
CGFloat colMargin = 10;

CGFloat itemW = (self.collectionView.frame.size.width - edge.left - edge.right - (column - 1)*colMargin)/column;
//        3.确定高度
//        3.1获取对应item的模型
LYShopModel *shop = self.shops[indexPath.item];
//    itemW/itemh = shop.width/shop.height;

CGFloat itemH = shop.height *itemW/shop.width;

//    CGFloat itmeH = 100+ arc4random_uniform(100);
//        4.确定位置

//        4.1获取最小的最大y值
//        4.2用一个值来记录最小的最大y值
CGFloat minMaxY = MAXFLOAT;
//        4.3记录最小的最大的y值所在的列号;
NSInteger minMaxCol = 0;
for (int i = 0; i <column; i ++) {
CGFloat maxY = [self.maxYs[i]doubleValue];
if (maxY < minMaxY) {
minMaxY = maxY;
minMaxCol = i;
}
}
//     4.4设置item的x值
CGFloat itemX = edge.left + (itemW + colMargin) *minMaxCol;
CGFloat itemY = minMaxY + rowMargin;
//    5.获取每一个对应位置的item的属性
UICollectionViewLayoutAttributes *attr = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
//    6.设置属性的frame
attr.frame = CGRectMake(itemX, itemY, itemW, itemH);
//    7.累加最小的最大的y值
//    minMaxY = CGRectGetMaxY(attr.frame);
self.maxYs[minMaxCol]= @(CGRectGetMaxY(attr.frame));

//    8.返回属性
return  attr;

}
/**
*  用来设置给定范围内所有的属性
*
*  @param rect <#rect description#>
*
*  @return <#return value description#>
*/
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{
// NSLog(@"调用了layoutAttributesForElementsInRect");
//    0.清空原来的所有的值
// [self.maxYs removeAllObjects];
//    1.设置数组的值
for (int i = 0 ; i <column;i ++) {
// [self.maxYs addObject:@(0)];
self.maxYs[i]=@(0);
}

//    2.创建可变数组
NSMutableArray *attrs = [NSMutableArray array];

//
//    3.获取所有的item的属性的个数
NSInteger count = [self.collectionView numberOfItemsInSection:0];
//    4.遍历多次,添加对应的属性值
for (int i = 0; i < count; i ++ ) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];

UICollectionViewLayoutAttributes *attr = [self layoutAttributesForItemAtIndexPath:indexPath];

[attrs addObject:attr];
//   NSLog(@"%@",attr);

}
return attrs;

}
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds{
//  NSLog(@"调用了shouldInvalidateLayoutForBoundsChange");
return YES;
}
/**
*  用来设置collectionView的滚动范围
*
*  @return <#return value description#>
*/

- (CGSize)collectionViewContentSize{
// NSLog(@"调用了collectionViewContentSize");
//    1.获取最大最大y值
CGFloat maxMaxY = 0;
//    1.1.记录最大的最大y值
if (self.maxYs.count) {
maxMaxY = [self.maxYs[0]doubleValue];
for (int i = 1; i < column; i ++) {
//        1.2获取每一个值
CGFloat maxY = [self.maxYs[i]doubleValue];
if (maxY > maxMaxY) {
maxMaxY = maxY;
}

}

}

return CGSizeMake(0, maxMaxY);

}

@end


//LYShopModel文件
#import <Foundation/Foundation.h>

@interface LYShopModel : NSObject
@property(nonatomic,copy)NSString *icon;
@property(nonatomic,copy)NSString *price;
@property(nonatomic,assign)int height;
@property(nonatomic,assign)int width;
- (instancetype)initWithDict:(NSDictionary *)dict;
+ (instancetype)shopWithDict:(NSDictionary *)dict;

@end

#import "LYShopModel.h"

@implementation LYShopModel

- (instancetype)initWithDict:(NSDictionary *)dict{

if (self = [super init]) {
[self setValuesForKeysWithDictionary:dict];
}
return self;
}
+ (instancetype)shopWithDict:(NSDictionary *)dict{

return [[self alloc]initWithDict:dict];
}

@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: