/**
* 瀑布流Demo的主要代码,若想看完整的代码请到下面链接去下载
*
* 链接: https://pan.baidu.com/s/1slByAHB 密码: r3q6
*/
#import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @end
#import "AppDelegate.h"
#import "RootViewController.h"
@interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor]; self.window.rootViewController = [[RootViewController alloc] init]; [self.window makeKeyAndVisible];
return YES;
} @end
#import <UIKit/UIKit.h>

@interface RootViewController : UIViewController

@end
#import "RootViewController.h"
#import "LFWaterfallLayout.h"
#import "XMGShop.h"
#import "MJExtension.h"
#import "MJRefresh.h"
#import "XMGShopCell.h"
@interface RootViewController ()<UICollectionViewDataSource,LFWaterfallLayoutDelegate> @property (nonatomic , strong) UICollectionView *collectionView;
/**
* 所有商品数据
*/
@property (nonatomic , strong) NSMutableArray *shops; @end @implementation RootViewController static NSString *const identifier = @"waterfall"; - (NSMutableArray *)shops{
if (!_shops) {
_shops = [NSMutableArray array];
}
return _shops;
} - (void)viewDidLoad {
[super viewDidLoad]; [self setupLayout]; [self setupRefresh];
} - (void)setupRefresh{
self.collectionView.header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewShops)];
[self.collectionView.header beginRefreshing]; self.collectionView.footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreShops)];
self.collectionView.footer.hidden = YES;
} - (void)loadNewShops{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSArray *shops = [XMGShop objectArrayWithFilename:@"1.plist"];
NSLog(@"%@",shops);
[self.shops removeAllObjects];
[self.shops addObjectsFromArray:shops];
// 刷新数据
[self.collectionView reloadData];
[self.collectionView.header endRefreshing];
});
} - (void)loadMoreShops{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSArray *shops = [XMGShop objectArrayWithFilename:@"1.plist"];
[self.shops addObjectsFromArray:shops];
// 刷新数据
[self.collectionView reloadData];
[self.collectionView.footer endRefreshing];
});
} - (void)setupLayout{
// 创建布局
LFWaterfallLayout *layout = [[LFWaterfallLayout alloc] init];
layout.delegate = self;
// 创建collecView
self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];
self.collectionView.backgroundColor = [UIColor whiteColor];
self.collectionView.dataSource = self;
[self.view addSubview:self.collectionView];
// 注册
[self.collectionView registerNib:[UINib nibWithNibName:NSStringFromClass([XMGShopCell class]) bundle:nil] forCellWithReuseIdentifier:identifier];
} #pragma mark -- UICollectionViewDataSource --
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
self.collectionView.footer.hidden = self.shops.count == ;
return self.shops.count;
} - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
XMGShopCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
cell.shop = self.shops[indexPath.item]; return cell;
} #pragma mark -- LFWaterfallLayoutDelegate --
- (CGFloat)waterflowLayout:(LFWaterfallLayout *)waterflowLayout heightForItemAtIndex:(NSUInteger)index itemWidth:(CGFloat)itemWidth{
XMGShop *shop = self.shops[index];
return itemWidth * shop.h / shop.w ;
} //- (CGFloat)rowMarginInWaterflowLayout:(LFWaterfallLayout *)waterflowLayout{
// return 30;
//} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} @end
#import <UIKit/UIKit.h>
@class LFWaterfallLayout; @protocol LFWaterfallLayoutDelegate <NSObject> @required
- (CGFloat)waterflowLayout:(LFWaterfallLayout *)waterflowLayout heightForItemAtIndex:(NSUInteger)index itemWidth:(CGFloat)itemWidth; @optional
- (CGFloat)columnCountInWaterflowLayout:(LFWaterfallLayout *)waterflowLayout;
- (CGFloat)columnMarginInWaterflowLayout:(LFWaterfallLayout *)waterflowLayout;
- (CGFloat)rowMarginInWaterflowLayout:(LFWaterfallLayout *)waterflowLayout;
- (UIEdgeInsets)edgeInsetsInWaterflowLayout:(LFWaterfallLayout *)waterflowLayout;
@end @interface LFWaterfallLayout : UICollectionViewLayout @property (nonatomic , weak) id<LFWaterfallLayoutDelegate> delegate; @end
#import "LFWaterfallLayout.h"

static const NSInteger LFDefaultColumnCount = ;//默认的列数
static const CGFloat LFDefaultColumnMargin = ;//每一列之间的间距
static const CGFloat LFDefaultRowMargin = ;//每一行之间的间距
static const UIEdgeInsets LFDefaultEdgeInsets = {,,,};//边缘间距 @interface LFWaterfallLayout ()
/**
* 存放所有cell的布局属性
*/
@property (nonatomic , strong) NSMutableArray *attrsArray;
/**
* 存放所有列的当前高度
*/
@property (nonatomic , strong) NSMutableArray *columnHeights; - (CGFloat)rowMargin;
- (CGFloat)columnMargin;
- (NSInteger)columnCount;
- (UIEdgeInsets)endgeInsets; @end @implementation LFWaterfallLayout #pragma mark -- 数据处理 --
- (CGFloat)rowMargin{
if ([self.delegate respondsToSelector:@selector(rowMarginInWaterflowLayout:)]) {
return [self.delegate rowMarginInWaterflowLayout:self];
}else{
return LFDefaultRowMargin;
}
} - (CGFloat)columnMargin{
if ([self.delegate respondsToSelector:@selector(columnMarginInWaterflowLayout:)]) {
return [self.delegate columnMarginInWaterflowLayout:self];
}else{
return LFDefaultColumnMargin;
}
} - (NSInteger)columnCount{
if ([self.delegate respondsToSelector:@selector(columnCountInWaterflowLayout:)]) {
return [self.delegate columnCountInWaterflowLayout:self];
}else{
return LFDefaultColumnCount;
}
} - (UIEdgeInsets)endgeInsets{
if ([self.delegate respondsToSelector:@selector(edgeInsetsInWaterflowLayout:)]) {
return [self.delegate edgeInsetsInWaterflowLayout:self];
}else{
return LFDefaultEdgeInsets;
} } - (NSMutableArray *)attrsArray{
if (!_attrsArray) {
_attrsArray = [NSMutableArray array];
}
return _attrsArray;
} - (NSMutableArray *)columnHeights{
if (!_columnHeights) {
_columnHeights = [NSMutableArray array];
}
return _columnHeights;
} /**
* 初始化
*/
- (void)prepareLayout{
[super prepareLayout];
// 清除以前计算的所有高度
[self.columnHeights removeAllObjects];
for (NSInteger i = ; i < self.columnCount; i++) {
[self.columnHeights addObject:@(self.endgeInsets.top)];
} // 清除之前所有的布局属性
[self.attrsArray removeAllObjects]; // 开始创建每一个cell对应的布局属性
NSInteger count = [self.collectionView numberOfItemsInSection:]; for (NSInteger i = ;i < count;i++) {
// 创建位置
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:]; // 获取indexPath位置对应cell的属性
UICollectionViewLayoutAttributes *attributes = [self layoutAttributesForItemAtIndexPath:indexPath]; [self.attrsArray addObject:attributes];
}
} /**
* 决定cell的布局
*/
- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect{ return self.attrsArray;
} /**
* 返回indexPath位置cell对应的布局属性
*/
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath{
// 创建布局属性
UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
//collectionView的宽度
CGFloat collectionViewWidth = self.collectionView.frame.size.width; // 找出高度最短的那一列
NSInteger shortestColumn = ;
// 找出最小高度
CGFloat minColumnHeight = [self.columnHeights[] doubleValue];
for (NSInteger i = ; i < self.columnCount; i++) {
// 取出第i列的高度
CGFloat columnHeight = [self.columnHeights[i] doubleValue];
// 比较大小
if (minColumnHeight > columnHeight) {
minColumnHeight = columnHeight;
shortestColumn = i;
}
}
// 宽度
CGFloat width = (collectionViewWidth - self.endgeInsets.left - self.endgeInsets.right - (self.columnCount - ) *self.columnMargin) / self.columnCount;
// x坐标
CGFloat x = self.endgeInsets.left + shortestColumn * (width + self.columnMargin);
// y坐标
CGFloat y = minColumnHeight;
if (y != self.endgeInsets.top) {
y += self.rowMargin;
} // 高度
CGFloat height = [self.delegate waterflowLayout:self heightForItemAtIndex:indexPath.item itemWidth:width];
//设置布局属性的frame
attributes.frame = CGRectMake(x,y, width, height); // 更新高度
self.columnHeights[shortestColumn] = @(CGRectGetMaxY(attributes.frame)); return attributes;
} - (CGSize)collectionViewContentSize{ // 找出最大高度
CGFloat maxColumnHeight = [self.columnHeights[] doubleValue];
for (NSInteger i = ; i < self.columnCount; i++) {
// 取出第i列的高度
CGFloat columnHeight = [self.columnHeights[i] doubleValue];
// 比较大小
if (maxColumnHeight < columnHeight) {
maxColumnHeight = columnHeight;
}
}
return CGSizeMake(, maxColumnHeight + self.endgeInsets.bottom);
} @end
#import <UIKit/UIKit.h>

@interface XMGShop : NSObject
@property (nonatomic, assign) CGFloat w;
@property (nonatomic, assign) CGFloat h;
@property (nonatomic, copy) NSString *img;
@property (nonatomic, copy) NSString *price;
@end
#import "XMGShop.h"

@implementation XMGShop

@end
#import <UIKit/UIKit.h>
@class XMGShop;
@interface XMGShopCell : UICollectionViewCell
@property (nonatomic, strong) XMGShop *shop;
@end
#import "XMGShopCell.h"
#import "XMGShop.h"
#import "UIImageView+WebCache.h" @interface XMGShopCell()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property (weak, nonatomic) IBOutlet UILabel *priceLabel;
@end @implementation XMGShopCell - (void)setShop:(XMGShop *)shop
{
_shop = shop; // 1.图片
[self.imageView sd_setImageWithURL:[NSURL URLWithString:shop.img] placeholderImage:[UIImage imageNamed:@"loading"]]; // 2.价格
self.priceLabel.text = shop.price;
}
@end

iOS 瀑布流的Demo的更多相关文章

  1. IOS 瀑布流UICollectionView实现

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

  2. iOS 瀑布流之栅格布局

    代码地址如下:http://www.demodashi.com/demo/14760.html 一 .效果预览 二.确定需求 由下面的需求示意图可知模块的最小单位是正方形,边长是屏幕宽除去边距间隔后的 ...

  3. iOS 瀑布流封装

    代码地址如下:http://www.demodashi.com/demo/12284.html 一.效果预览 功能描述:WSLWaterFlowLayout 是在继承于UICollectionView ...

  4. IOS 瀑布流

    本篇博客应该算的上CollectionView的高级应用了,从iOS开发之窥探UICollectionViewController(一)到今天的(五),可谓是由浅入深的窥探了一下UICollectio ...

  5. ios 瀑布流的那些事情

    转载: 屎壳郎情调-成长日记 首先要知道:瀑布流的核心就是要获取到图片的长宽 网上的很多例子都是加载本地图片的 对于新手而言 改成加载网络图片的确是有点压力的  因为本地的图片 我们是很容易就能获取到 ...

  6. iOS瀑布流实现(Swift)

    这段时间突然想到一个很久之前用到的知识-瀑布流,本来想用一个简单的方法,发现自己走入了歧途,最终只能狠下心来重写UICollectionViewFlowLayout.下面我将用两种方法实现瀑布流,以及 ...

  7. iOS 瀑布流的基本原理

    /** * 源代码链接 * 链接: https://pan.baidu.com/s/1nvLamEX 密码: kya5 */ #import <UIKit/UIKit.h> @interf ...

  8. ios瀑布流

    http://blog.csdn.net/shenjx1225/article/details/9037631

  9. iOS开发笔记15:地图坐标转换那些事、block引用循环/weak–strong dance、UICollectionviewLayout及瀑布流、图层混合

    1.地图坐标转换那些事 (1)投影坐标系与地理坐标系 地理坐标系使用三维球面来定义地球上的位置,单位即经纬度.但经纬度无法精确测量距离戒面积,也难以在平面地图戒计算机屏幕上显示数据.通过投影的方式可以 ...

随机推荐

  1. WEB-INF目录下的jsp页面如何访问?

    只能在sevlet(或者spring的control,struts的action,本质都是sevlet)中访问也就是只能通过java后台访问,这里web-inf下的内容是不对外开放的/安全的,不能通过 ...

  2. 20145235李涛《Java程序设计》第一周学习总结

    教材学习内容总结 JAVA三大平台:Java SE(针对企业).Java EE(针对开发者) .Java ME(针对开发小型消费类电子产品) 其他 Java SE四个组成部分:JVM .JRE. JD ...

  3. cookie 操作

    //创建并赋值 重新赋值也是这样操作 document.cookie="userId=828"; document.cookie="userName=hulk" ...

  4. 蓝牙4.0(包含BLE)简介

    1. BLE   (低功耗蓝牙)简介 国际蓝牙联盟( BT-SIG,TI  是 企业成员之一)通过的一个标准蓝牙无线协议. 主要的新特性是在蓝牙标准版本上添加了4.0 蓝牙规范 (2010 年6 月 ...

  5. 删除本地git版本库中受版本控制的文件

     git乱码解决方案汇总 乱码原因 搜索一番,发现git文件名.log乱码,是普遍问题,这其中有编码的原因,也有跨平台的原因.主要原因是Windows 系统中的Git对中文文件名采用不同的编码保存所致 ...

  6. 关于<a href='javascript:function()'>

    <a href='javascript:function()'> 这样写是为了让这个链接不要链接到新页面转而执行一段js代码.和onclick能起到同样的效果,一般来说,如果要调用脚本还是 ...

  7. php--yii框架表单验证

    在视图层利用表单小部件生成表单时,field只能是数据库中存在的, 例如: use yii\helpers\Html; use yii\widgets\ActiveForm; use yii\capt ...

  8. php---文件上传分析

    文件上传: 先抄一段:预定义变量$_FILES数组有5个内容:       $_FILES['userfile']['name']——客户端机器文件的原名称       $_FILES['userfi ...

  9. CentOS 6.3下PostgreSQL 的安装与配置

    一.简介 PostgreSQL 是一种非常复杂的对象-关系型数据库管理系统(ORDBMS),也是目前功能最强大,特性最丰富和最复杂的自由软件数据库系统.有些特性甚至连商业数据库都不具备.这个起源于伯克 ...

  10. Dictionary、SortedDictionary、Hashtable 、SortedList

    HashTable数据结构存在问题:空间利用率偏低.受填充因子影响大.扩容时所有的数据需要重新进行散列计算.虽然Hash具有O(1)的数据 检索效率,但它空间开销却通常很大,是以空间换取时间.所以Ha ...