【代码笔记】自定义布局实现瀑布流
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
相关文章推荐
- Java图形界面
- java基础总结第一篇(JAVA简介)
- python---通过networkx使图着色结果可视化
- Spring MVC返回json数据的配置方式
- 第一行代码-13.2 使用Intent传递对象
- C++上机报告(一)
- ASP.NET数据绑定GridView控件使用技巧
- python套接字流重定向实例汇总
- Python和Perl绘制中国北京跑步地图的方法
- Python中的数据对象持久化存储模块pickle的使用示例
- 举例简单讲解Python中的数据存储模块shelve的用法
- Python程序中用csv模块来操作csv文件的基本使用教程
- 浅析php设计模式之数据对象映射模式
- 简单介绍PHP非阻塞模式
- php编程每天必学之验证码
- php轻松实现文件上传功能
- PHP6新特性分析
- PHP的数组中提高元素查找与元素去重的效率的技巧解析
- 将PHP程序中返回的JSON格式数据用gzip压缩输出的方法
- Java支持的数据类型有哪些?什么是自动拆装箱?