一、瀑布流简介

瀑布流,又称瀑布流式布局。是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。最早采用此布局的网站是Pinterest,逐渐在国内流行开来。国内大多数清新站基本为这类风格

二、瀑布流特点

l 琳琅满目:整版以图片为主,大小不一的图片按照一定的规律排列

l 唯美:图片的风格以唯美的图片为主

l 操作简单:在浏览网站的时候只需要轻轻滑动一下鼠标滚轮,一切的美妙的图片精彩便可呈现在你面前

三、瀑布流应用

瀑布流对于图片的展现,是高效而具有吸引力的,用户一眼扫过的快速阅读模式可以在短时间内获得更多的信息量,而瀑布流里懒加载模式又避免了用户鼠标点击的翻页操作

瀑布流的主要特性便是错落有致,定宽而不定高的设计让页面区别于传统的矩阵式图片布局模式,巧妙的利用视觉层级,视线的任意流动又缓解了视觉疲劳

四、使用瀑布流的网站

l 电商导购,如想去网、蘑菇街和美丽说、好享说,依托于淘宝平台

l 兴趣图谱分享,如知美、花瓣等

l 细分垂直领域,如针对吃货的零食控、针对家居行业的他部落等

五、瀑布流的优缺点

l 优点

有效的降低了界面复杂度,节省了空间:我们不再需要臃肿复杂的页码导航链接或按钮了

对触屏设备来说,交互方式更符合直觉:在移动应用的交互环境当中,通过向上滑动进行滚屏的操作已经成为最基本的用户习惯,而且所需要的操作精准程度远远低于点击链接或按钮

更高的参与度:以上两点所带来的交互便捷性可以使用户将注意力更多的集中在内容而不是操作上,从而让他们更乐于沉浸在探索与浏览当中

l 缺点

有限的用例:无限滚动的方式只适用于某些特定类型产品当中一部分特定类型的内容

额外的复杂度

l SEO:集中在一页当中动态加载数据,不利于SEO,对于网站而言,存在一定的风险

l 页面的数量:如果网站需要通过更多的内容页面展示更多的相关信息(包括广告)是很重要的策略,那么单页无限滚动的方式就不适用了

六、实现瀑布流的思路

使用多个UITableView,控制它们同时滚动,在复杂的用户操作下,会出现滚动不同步的情况;如果需要支持设备的多个方向,不利于增加图片列数及方向切换的动画效果,使用一个UIScrollView,参考UITableView的实现方式,开发一个符合需求的可重用的控件

七、瀑布流数据处理思路

每次通过一个GET方法加载一个JSON数据,数据中包含一组数据信息:图像URL、图像标题等

异步加载JSON数据包中的图像,从左至右,从上至下依次显示

滚动至数据末尾时,加载新的数据

数据加载后,从当前最末一张图像开始追加新的图像

滚动至顶部时,下拉刷新新的数据

新数据加载后,重新填充当前视图中的内容

八、开发步骤

使用沙箱数据:自定义UIScrollView,使用沙箱中的图像模拟瀑布流的实现

集成网络:通过网络加载并处理数据

九、自定义瀑布流控件

自定义UIScrollView(WaterFlowView),模拟UITableView

自定义UIView(WaterFlowViewCell),模拟UITableViewCell

单独负责图像内容及文本标签的显示

使用可重用标示符处理视图的重用

自定义UIViewController(WaterFlowViewController),模拟UITableViewController

处理自定义UIScrollView的数据源及代理方法

十、WaterFlowViewCell的定义

属性

// 可重用标示符

@property (strong, nonatomic) NSString *reuseIdentifier;

// 被选中标记

@property (assign, nonatomic) BOOL selected;

// 图像视图

@property (weak, nonatomic) UIImageView *imageView;

// 文本标签

@property (weak, nonatomic) UILabel *textLabel;

方法:

// 使用可重用标示符实例化视图

- (id)initWithResueIdentifier:(NSString *)reusedIdentifier;

十一、WaterFlowViewCell的实现

利用控件的getter方法实现控件懒加载

重写layoutSubviews方法,调整控件布局

注意:此处不需要调用父类的layoutSubViews方法

十二、WaterFlowView的定义数据源和代理

l 数据源

单元格数量

l 单元格

视图的列数(默认为1,可选方法)

l 代理

指定单元格的高度

单元格被选中

十三、数据源协议

@protocol WaterFlowViewDataSource <NSObject>

// 单元格数量

- (NSInteger)waterFlowViewNumberOfCells:(WaterFlowView *)waterFlowView;

// 单元格

- (WaterFlowViewCell *)waterFlowView:(WaterFlowView *)waterFlowView cellAtIndexPath:(NSIndexPath *)indexPath;

@optional

// 视图的列数(可选,默认1列)

- (NSInteger)waterFlowViewNumberOfColumns:(WaterFlowView *)waterFlowView;

@end

十四、代理协议

@protocol WaterFlowViewDelegate <UIScrollViewDelegate>

// 指定单元格的高度

- (CGFloat)waterFlowView:(WaterFlowView *)waterFlowView heightForCellAtIndexPath:(NSIndexPath *)indexPath;

// 单元格被选中

- (void)waterFlowView:(WaterFlowView *)waterFlowView didSelectedCellAtIndexPath:(NSIndexPath *)indexPath;

@end

十五、WaterFlowViewController中的实例化视图

- (void)loadView

{

_waterFlowView = [[WaterFlowView alloc]initWithFrame:CGRectZero];

[_waterFlowView setDataSource:self];

[_waterFlowView setDelegate:self];

// 根据父视图大小调整自身大小

[_waterFlowView setAutoresizingMask:UIViewAutoresizingFlexibleWidth

| UIViewAutoresizingFlexibleHeight];

self.view = _waterFlowView;

}

十六、编写resetView方法实现瀑布流视图的布局

1. 首先初始化根据数据行数indexPaths数组

2. 布局界面

1) 计算每列宽度

2) 使用一个数组,记录每列的当前Y值

3) 遍历self.indexPaths生成WaterFlowCellView并计算位置

4) 设置scrollView的contentSize

十七、修改WaterFlowViewController增加方向支持

#pragma mark 设备旋转结束

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation

{

[self.waterFlowView reloadData];

}

#pragma mark - 列数

- (NSInteger)numberOfColumnsInWaterFlowView:(WaterFlowView *)waterFlowView

{

// 根据设备方向设定不同的瀑布流列数

if ([UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft || [UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeRight) {

self.numberOfColumns = 4;

} else {

self.numberOfColumns = 3;

}

return self.numberOfColumns;

}

十八、引入缓存策略,利用数据字典记录单元格的位置

#pragma mark - 缓存数据

// 单元格位置数组

@property (strong, nonatomic) NSMutableArray *cellFramesArray;

// 单元格缓存集合

@property (strong, nonatomic) NSMutableSet *reusableCellSet;

// 正在显示单元格字典

@property (strong, nonatomic) NSMutableDictionary *screenCellsDict;

编写方法统一生成缓存数据

// 建立缓存数据

[self generateCacheData];

十九、生成缓存数据

// 1) 获取当前列数

// 2) 建立列索引数组

// 3) 建立列单元格位置数组

// 4) 建立整体索引数组

// 5. 视图缓存字典

// 6. 正在显示的单元格集合

二十、修改resetView方法,仅记录各个视图位置

// 计算出下一列的数值

NSInteger nextCol = (col + 1) % _numberOfColumns;

// 判断当前的行高是否超过下一列的行高

if (currentY[col] > currentY[nextCol]) {

col = nextCol;

}

// 在单元格数组中记录所有单元格的位置(位置&大小)

[self.cellFramesArray addObject:[NSValue valueWithCGRect:CGRectMake(x, y, colW, h)]];

二十一、判断视图是否在屏幕范围之内

#pragma mark 判断视图是否在屏幕范围之内

- (BOOL)isInScreenWithFrame:(CGRect)frame

{

return (frame.origin.y - self.contentOffset.y) < self.bounds.size.height &&

(frame.origin.y + frame.size.height - self.contentOffset.y) > 0;

}

二十二、编写dequeueReusableCellWithReuseIdentifier

#pragma mark 使用可重用标示符获取单元格对象

- (WaterFlowCellView *)dequeueReusableCellWithReuseIdentifier:(NSString *)reuseIdentifier

{

// 需要从一个集合获取可重用单元格

// 从集合中取出任意对象

WaterFlowCellView *cell = [self.reusableCellSet anyObject];

if (cell != nil) {

// 从集合中删除视图

[self.reusableCellSet removeObject:cell];

}

return cell;

}

二十三、手势处理

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

UITouch *touch = [touches anyObject];

CGPoint location = [touch locationInView:self];

// 遍历可见视图集合,查找被点击的单元格

NSArray *array = [self.displayCellDict allKeys];

for (NSIndexPath *indexPath in array) {

WaterFlowCellView *view = self.displayCellDict[indexPath];

if (CGRectContainsPoint(view.frame, location)) {

[self.delegate waterFlowView:self didSelectRowAtIndexPath:indexPath];

}

}

}

iOS基础 - 瀑布流的更多相关文章

  1. ios图片瀑布流代码

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

  2. iOS横向瀑布流的封装

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

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

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

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

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

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

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

  6. iOS开发瀑布流的实现

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

  7. iOS开发之窥探UICollectionViewController(四) --一款功能强大的自定义瀑布流

    在上一篇博客中<iOS开发之窥探UICollectionViewController(三) --使用UICollectionView自定义瀑布流>,自定义瀑布流的列数,Cell的外边距,C ...

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

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

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

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

随机推荐

  1. 【通过做专题研习Android】知识点:SharedPreferences

    Ⅰ. 一个简短的引论 很多时候我们需要开发软件,为用户提供软件参数设置功能,比如,我们经常使用 QQ.用户可以设置自己是否同意加入一个陌生人为好友.对于软件的配置参数的存储,假设window採用ini ...

  2. OJ提交题目中的语言选项里G++与C++的区别(转载)

    原文链接:http://blog.polossk.com/201405/c-plus-plus-g-plus-plus G++? 首先更正一个概念,C++是一门计算机编程语言,G++不是语言,是一款编 ...

  3. idea_intellij

    近期要研读和调试spark2,用eclispe据说各种问题,so还是切换到  intellij 1:下载 (官网自行下载最新版本) 2: 注册码 intellij idea 2016 activati ...

  4. sicily 1007 To and Fro (基地称号)

    链接:http://soj.me/show_problem.php?pid=1007 Description Mo and Larry have devised a way of encrypting ...

  5. js之with

    网上找资料的时候看到有js代码里出现了大量的with语句,有点好奇,这里做下总结: 1)简要说明         with 语句可以方便地用来引用某个特定对象中已有的属性,但是不能用来给对象添加属性. ...

  6. kubernetes多节点部署的决心

    注:以下操作均基于centos7系统. 安装ansible ansilbe能够通过yum或者pip安装,因为kubernetes-ansible用到了密码.故而还须要安装sshpass: pip in ...

  7. ajax提交与上传文件同步

    我们经常担心文件上传,最烦比,可以推断,我们上传的文件大小,格风格等等一系列的推理验证.所以,我们只能ajax提交验证.ajax异步提交太麻烦,我想太多的变化代码,事实上,我们使用JQuery当插件, ...

  8. 乐趣与你rabbitMQ 源代码

    RabbitMQ API RabbitMQ Server它提供了丰富的http api. 对于列子 须要HTTP基本身份验证.默认的username/password为guest/guest. 这些返 ...

  9. easyui 小知识

    默认为今天 $(document).ready(function () {        $(function () {            var curr_time = new Date();  ...

  10. OpenVPN多实例优化的思考过程

    1.sss 当构建组件之间的关系已经错综复杂到接近于一张全然图的时候,就要换一个思路了,或者你须要重构整个系统,或者你将又一次实现一个. 2.TAP网卡和TUN网卡 2.1.TAP的优势 1.方便组网 ...