ViewController.m

 //
// ViewController.m
// IOS_0227_瀑布流
//
// Created by ma c on 16/2/27.
// Copyright © 2016年 博文科技. All rights reserved.
// #import "ViewController.h"
#import "WaterFlowLayout.h"
#import "MJExtension.h"
#import "MJRefresh.h"
#import "HMShop.h"
#import "ShopCell.h" @interface ViewController ()<UICollectionViewDataSource,UICollectionViewDelegate,WaterFlowLayoutDelegate> @property (nonatomic, weak) UICollectionView *collectionView;
@property (nonatomic, strong) NSMutableArray *shops; @end @implementation ViewController static NSString *ID = @"shop"; - (void)viewDidLoad {
[super viewDidLoad]; //初始化数据
NSArray *shopArray = [HMShop objectArrayWithFilename:@"1.plist"];
[self.shops addObjectsFromArray:shopArray]; [self createUI];
} - (NSMutableArray *)shops
{
if (!_shops) {
_shops = [NSMutableArray array];
}
return _shops;
} - (void)createUI
{
// CGRect rect = CGRectMake(7, 100, 400, 200);
WaterFlowLayout *layout = [[WaterFlowLayout alloc] init];
UICollectionView *collection = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];
collection.backgroundColor = [UIColor groupTableViewBackgroundColor];
layout.delegate = self;
collection.dataSource = self;
collection.delegate = self;
[collection registerNib:[UINib nibWithNibName:@"ShopCell" bundle:nil] forCellWithReuseIdentifier:ID];
[self.view addSubview:collection];
self.collectionView = collection;
[self.collectionView addFooterWithTarget:self action:@selector(loadMoreShops)];
} - (void)loadMoreShops
{
//初始化数据
NSArray *shopArray = [HMShop objectArrayWithFilename:@"1.plist"];
[self.shops addObjectsFromArray:shopArray]; [self.collectionView reloadData]; [self.collectionView footerEndRefreshing];
} #pragma mark - WaterFlowLayoutDelegate - (CGFloat)waterFlowLayout:(WaterFlowLayout *)waterFlowLayout heightForWidth:(CGFloat)width atIndexPath:(NSIndexPath *)indexPath
{
HMShop *shop = self.shops[indexPath.item];
return shop.height / shop.width * width;
} #pragma mark - UICollectionViewDataSource - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return self.shops.count;
} - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
ShopCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath]; cell.shop = self.shops[indexPath.item]; return cell;
} @end

WaterFlowLayout.m

 //
// WaterFlowLayout.h
// IOS_0227_瀑布流
//
// Created by ma c on 16/2/27.
// Copyright © 2016年 博文科技. All rights reserved.
// #import <UIKit/UIKit.h>
@class WaterFlowLayout; @protocol WaterFlowLayoutDelegate <NSObject> - (CGFloat)waterFlowLayout:(WaterFlowLayout *)waterFlowLayout heightForWidth:(CGFloat)width atIndexPath:(NSIndexPath *)indexPath; @end @interface WaterFlowLayout : UICollectionViewLayout @property (nonatomic, assign) UIEdgeInsets sessionInset;
//列间距
@property (nonatomic, assign) CGFloat columnMargin;
//行间距
@property (nonatomic, assign) CGFloat rowMargin;
//列数
@property (nonatomic, assign) int columnCount; @property (nonatomic, strong) id<WaterFlowLayoutDelegate> delegate; @end //
// WaterFlowLayout.m
// IOS_0227_瀑布流
//
// Created by ma c on 16/2/27.
// Copyright © 2016年 博文科技. All rights reserved.
// #import "WaterFlowLayout.h" @interface WaterFlowLayout ()
//存储每列最大高度Y值
@property (nonatomic, strong) NSMutableDictionary *maxYDict;
@property (nonatomic, strong) NSMutableArray *attrsArray; @end @implementation WaterFlowLayout - (instancetype)init
{
self = [super init];
if (self) {
self.rowMargin = ;
self.columnMargin = ;
self.sessionInset = UIEdgeInsetsMake(, , , );
self.columnCount = ;
}
return self;
} - (NSMutableDictionary *)maxYDict
{
if (!_maxYDict) {
_maxYDict = [[NSMutableDictionary alloc] init];
for (int i = ; i < self.columnCount; i++) {
NSString *column = [NSString stringWithFormat:@"%d",i];
_maxYDict[column] = @(self.sessionInset.top);
//NSLog(@"%@",_maxYDict); }
}
return _maxYDict;
} - (NSMutableArray *)attrsArray
{
if (!_attrsArray) {
_attrsArray = [NSMutableArray array];
}
return _attrsArray;
} //布局前准备
- (void)prepareLayout
{
[super prepareLayout];
//NSLog(@"layoutAttributesForElementsInRect"); //清空最大Y值
for (int i = ; i < self.columnCount; i++) {
NSString *column = [NSString stringWithFormat:@"%d",i];
_maxYDict[column] = @;
}
//计算item属性
[self.attrsArray removeAllObjects];
NSInteger count = [self.collectionView numberOfItemsInSection:]; for (int i=; i<count; i++) {
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:];
UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:indexPath];
[self.attrsArray addObject:attrs];
}
} - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
return YES;
} //尺寸
- (CGSize)collectionViewContentSize
{
//NSLog(@"collectionViewContentSize");
//假设最长的那一列是第0列
__block NSString *maxYColumn = @"";
//找出最长的那一列
[self.maxYDict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
if ([obj floatValue] > [self.maxYDict[maxYColumn] floatValue]) {
maxYColumn = key;
}
}];
return CGSizeMake(, [self.maxYDict[maxYColumn] floatValue] + self.sessionInset.bottom);
}
//rect范围内的布局属性
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
// //NSLog(@"layoutAttributesForElementsInRect");
//
// for (int i = 0; i < self.columnCount; i++) {
// NSString *column = [NSString stringWithFormat:@"%d",i];
// _maxYDict[column] = @0;
// }
//
// NSMutableArray *array = [NSMutableArray array];
// NSInteger count = [self.collectionView numberOfItemsInSection:0];
//
// for (int i=0; i<count; i++) {
// NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
// UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:indexPath];
// [array addObject:attrs];
//
// }
// return array;
return self.attrsArray;
}
//indexPath位置的item的布局属性
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
//NSLog(@"layoutAttributesForItemAtIndexPath");
//假设最短的那一列是第0列
__block NSString *minYColumn = @"";
//找出最短的那一列
[self.maxYDict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
if ([obj floatValue] < [self.maxYDict[minYColumn] floatValue]) {
minYColumn = key;
}
}];
//NSLog(@"%@",minYColumn); //计算尺寸
CGFloat width = (self.collectionView.frame.size.width - self.sessionInset.left - self.sessionInset.right - (self.columnCount - ) * self.columnMargin) / self.columnCount;
CGFloat height = [self.delegate waterFlowLayout:self heightForWidth:width atIndexPath:indexPath]; //计算位置
CGFloat x = self.sessionInset.left + (width + self.columnMargin) * [minYColumn intValue];
CGFloat y = [self.maxYDict[minYColumn] floatValue] + self.rowMargin; //更新这一列最大Y值
self.maxYDict[minYColumn] = @(y + height); //创建属性
UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
attrs.frame = CGRectMake(x, y, width, height); return attrs;
}
@end

ShopCell.m

 //
// ShopCell.h
// IOS_0227_瀑布流
//
// Created by ma c on 16/2/27.
// Copyright © 2016年 博文科技. All rights reserved.
// #import <UIKit/UIKit.h>
@class HMShop;
@interface ShopCell : UICollectionViewCell @property (nonatomic, strong) HMShop *shop; @end //
// ShopCell.m
// IOS_0227_瀑布流
//
// Created by ma c on 16/2/27.
// Copyright © 2016年 博文科技. All rights reserved.
// #import "ShopCell.h"
#import "HMShop.h" @interface ShopCell () @property (weak, nonatomic) IBOutlet UIImageView *imgView;
@property (weak, nonatomic) IBOutlet UILabel *lblPrice; @end @implementation ShopCell - (void)awakeFromNib {
// Initialization code
} - (void)setShop:(HMShop *)shop
{
_shop = shop; self.imgView.image = [UIImage imageNamed:shop.icon];
self.lblPrice.text = shop.price; } @end

HMShop.m

 //
// HMShop.h
// 05-黑马瀑布流
//
// Created by Romeo on 15/11/25.
// Copyright © 2015年 itheima. All rights reserved.
// #import <UIKit/UIKit.h> @interface HMShop : NSObject
// 图片
@property (nonatomic, copy) NSString *icon;
// 价格
@property (nonatomic, copy) NSString *price;
// 图片的真实高度
@property (nonatomic, assign) CGFloat height;
// 图片的真实宽度
@property (nonatomic, assign) CGFloat width; + (instancetype)shopWithDict:(NSDictionary *)dict; @end //
// HMShop.m
// 05-黑马瀑布流
//
// Created by Romeo on 15/11/25.
// Copyright © 2015年 itheima. All rights reserved.
// #import "HMShop.h" @implementation HMShop + (instancetype)shopWithDict:(NSDictionary *)dict {
id obj = [[self alloc] init];
[obj setValuesForKeysWithDictionary:dict];
return obj;
} @end

IOS UI-瀑布流(UICollectionView)的更多相关文章

  1. IOS 瀑布流UICollectionView实现

    IOS 瀑布流UICollectionView实现 在实现瀑布流之前先来看看瀑布流的雏形(此方法的雏形 UICollectionView) 对于UICollectionView我们有几点注意事项 它和 ...

  2. iOS横向瀑布流的封装

    前段时间, 做一个羡慕, 需要使用到瀑布流! 说道瀑布流, 或许大家都不陌生, 瀑布流的实现也有很多种! 从scrollView 到 tableView 书写的瀑布流, 然后再到2012年iOS6 苹 ...

  3. ios图片瀑布流代码

    ios瀑布流,实现简单的瀑布流视图布局,可以显示网络图片,下拉刷新,上拉加载更多. 下载:http://www.huiyi8.com/sc/9087.html

  4. iOS基础 - 瀑布流

    一.瀑布流简介 瀑布流,又称瀑布流式布局.是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部.最早采用此布局的网站是Pint ...

  5. ios开发瀑布流框架的应用

    一:瀑布流框架的应用:将封装好的瀑布流框架导入,遵守协议 二:代码: #import "HMShopsViewController.h" #import "HMShopC ...

  6. ios开发瀑布流框架的封装

    一:瀑布流框架封装的实现思路:此瀑布流框架的封装仿照tableView的底层实现,1:每个cell的frame的设置都是找出每列的最大y值,比较每列的最大y值,将下一个cell放在最大y值最小的那一列 ...

  7. iOS开发瀑布流的实现

    //自定义布局,继承于UICollectionViewLayout #import <UIKit/UIKit.h> @class WaterFlowLayout; @protocol  W ...

  8. iOS开发之窥探UICollectionViewController(三) --使用UICollectionView自定义瀑布流

    上篇博客的实例是自带的UICollectionViewDelegateFlowLayout布局基础上来做的Demo, 详情请看<iOS开发之窥探UICollectionViewControlle ...

  9. iOS开发-UICollectionView实现瀑布流

    关于瀑布流的实现网上有很多种解法,自定义控件,TableView+ScrollView,UICollectionView是iOS6发布之后用于展示集合视图,算起来已经发布三年左右了,不过知识点是不变的 ...

  10. iOS - UICollectionView 瀑布流 添加表头视图的坑

    UICollectionView 瀑布流 添加表头视图的坑 首先是,需求加了个头视图在顶部,在collectionView中的头视图跟TableView的不一样,TableView的表头只要设置tab ...

随机推荐

  1. vmware12 安装linux centos6

          内核选 2.6                                                                 中文安装选 基本系统 -> 基本, 兼 ...

  2. 数据库(11)-- Hash索引和BTree索引 的区别

    索引是帮助mysql获取数据的数据结构.最常见的索引是Btree索引和Hash索引. 不同的引擎对于索引有不同的支持:Innodb和MyISAM默认的索引是Btree索引:而Mermory默认的索引是 ...

  3. 转:WebClient类(温习一下)

    WebClient类提供向 URI 标识的资源发送数据和从 URI 标识的资源接收数据的公共方法. 其实就相当于创建一个请求客户端.可以获取网页和各种各样的信息,包括交互. 通过MSDN来看看WebC ...

  4. Miller_Rabbin大素数测试

    伪素数: 如果存在和n互素的正整数a满足a^(n-1)≡1(mod n),则n是基于a的伪素数. 是伪素数但不是素数的个数是非常非常少的,所以如果一个数是伪素数,那么他几乎是素数. Miller_Ra ...

  5. java中的重量级与轻量级概念

    首先轻量级与重量级是一个相对的概念,主要是对应用框架使用方便性和所提供服务特性等方面做比较的. 比方说EJB就是一个重量级的框架,因为它对所编写的代码有限制,同时它也提供分布式等复杂的功能. 相比之下 ...

  6. 网络虚拟化 SDN

    一.Linux Bridge :Linux中的网桥 假设宿主机有 1 块与外网连接的物理网卡 eth0,上面跑了 1 个虚机 VM1,现在有个问题是: 如何让 VM1 能够访问外网? 至少有两种方案 ...

  7. DevOps简单介绍

    jenkins作为测试环境代码发布工具,sonar作为静态代码检查工具,idea作为开发工具,jira作为缺陷管理平台,upstream作为code review工具(正在研究).DevOps最近比较 ...

  8. Web安全学习笔记之Nmap扫描原理与用法

    1     Nmap介绍 Nmap扫描原理与用法PDF:下载地址 Nmap是一款开源免费的网络发现(Network Discovery)和安全审计(Security Auditing)工具.软件名字N ...

  9. Spring使用事务

    Spring使用事务,一共有4个步骤 1.配置数据源 例如: <bean id="dataSource" class="com.mchange.v2.c3p0.Co ...

  10. linux 安装vscode

    滚动安装vscode 需要先添加源,然后install 以centos为例: sudo rpm --import https://packages.microsoft.com/keys/microso ...