相信大家有很多人在做项目的时候都在使用MJRefresh 控件来实现下拉刷新的功能;
MJRefresh经过不断的重构与更新迭代,现在不管是功能上还是代码结构上都是相当不错的,都是很值我们去学习的.

下面就是MJRefresh开源框架中中主要的一些类文件

MJRefresh主要的类文件
MJRefresh 的使用相信都难不倒大家

今天我主要想和大家分享一下MJRefresh的想法,因为我觉得这才是最重要的,献丑了,有理解的不对和不深入的地方,请大家多多点评哈!


试想,如果没有MJRefresh开源框架,公司让你来写这样一个框架?
  • 你应该怎么写?
  • 应该从哪几个方面考虑?
  • 应该怎么下手?
  • 应该注意一些什么?

下面我分了六个步骤给大家说一下

  • 第 1 步: 主要说了一下大体思路和注意事项
  • 第 2 步:为什么使用UIScrollView ?
  • 第 3 步:如何给UIScrollView增加新的属性header ?
  • 第 4 步:Header类里主要写一些什么 ?
  • 第 5 步:如何利用KVO的方式来监听偏移量的变化(设置刷新状态)?
  • 第 6 步:实例化Header类的对象 去给 UIScrollView的属性header赋值 ?

step1: 

如果想给UITableView 和UICollectionView 增加下拉刷新 上提加载的功能

其实不要想的太复杂,其实就是给他们:


1.先增加一个头视图(header) 和 尾视图(footer)
2.然后就是考虑状态的变化(正在刷新啊,刷新完成啊),通过偏移量来判断
3.最后给这些状态设置一些监听事件(下拉刷新的时候调用什么方法,没有数据了调用什么方法等)

如果能实现上面几点的话,一个简单粗糙的下拉刷新的控件就可以实现了

但是具体操作的时候我们还是要考虑几点问题:
  • 1.首先要满足以后能够很方便给TableView和CollectionView的去增加这个特性,
  • 2.能够很好的去适配最新的SDK
  • 3.增加特性后要减少甚至避免此特性(下拉刷新)不与其它UI控件和其他特性发生冲突

根据上面的几点问题我们有以下两种选择:
  • 1.自己重写一套UIScrollView并且加上下拉刷新的特性(但是很有难度,不建议这样);

  • 2.最好的方式是使用IOS的特性Category来增加下拉刷新的功能(选择这种方式来实现);


step2:

接下来我们要考虑的就是给TableView加还是给UICollectionView?(其实很简单,大神们可以忽略这个问题)我们选择的是UIScrollView


为什么使用ScrollView?而不使用TableView 和 CollectionView增加Category ?
大家应该都知道 UITableView 和 UICollectionView 都是继承于 ScrollView
如果我们使用UIScrollView的话,以后不管是tableView 和 CollectionView都可以直接使用下拉刷新的特性
但我们如果使用UITableView的话,我们肯定还必须为UICollectionView 写一套新的下拉刷新的方法;使用UIScrollView 会很大程度上提高我们这个下拉组件的延展性和兼容性


step3:

接下来就是需要来考虑我们如何使用UIScrollView和Catgory的特性来增加下拉刷新和上提加载的功能 ? ? ?

满足下面两点:
1.下拉刷新?上提加载?
2.为了方便以后容易使用?


最好的方式是 给UIScrollView 添加两个属性 一个是header 一个是Footer ,这样以后就可以直接利用这两个属性做事情了;

这个时候我们就需要考虑给UIScrollView添加属性了,如何给UIScrollView添加属性?

有点IOS基础的应该都知道,我们不能直接给Category添加属性;
但是可用通过采用动态添加属性的方法objc_setAssociatedObject()和objc_getAssociatedObject()函数给UIScrollView动态添加属性
这是一种关联对象的技巧(AssociatedObject)

给UIScrollView增加header属性

当然添加Footer的方法也是这样,添加Footer的时候只需要修改一下Key 就好,就先不讲Footer的实现了



step4:

既然添加完属性,那此时我们就需要想着如何给属性赋值?

所以接下来我们的工作就是写一个header的类

然后用Header类的对象给我们新增加的scrollView的header属性赋值

#当然现在MJRefresh这个框架已经进行了代码重构,现在框架的结构比较清晰,但是对一些刚开始接触IOS的同学看起来就会有些费劲了_
#现在咱们只讲一些主要的代码,先不考虑MJRefresh的代码结构
#因为它现在的代码是重构之后的,而咱们现在讲的是实现的思路
#先按照我们正常的思路来分析一下
首先创建一个类Header去继承UIView 但header类里面要写什么呢?
  • 1.首先肯定少不了一些主要的布局 如 下拉的ImageView,以及UIActivityIndicatorView等
  • 2.其次是 下拉刷新那一块会有很多的状态的变化,比如 正在刷新中,刷新完成,刚开始刷新等状态的判断,(这些状态我们需要通过 UIScrollView 的偏移量来计算这些状态。这一块主要就是一些逻辑判断,如何计算这次暂时不讲了
  • 3.最后就是看需求了,如果需要时间的加时间,需要GIF的加GIF动画;

普通的Header

带GIF的header

step5:

如何计算刷新状态呢 ?
所以此时我们不得不需要另一个知识点:事件监听(监听 UIScrollView的偏移量变化情况);
说到监听的话,IOS有几种经典的方式用来监听(以后有时间会给大家讲一下它们的优缺点和用法):
  • 1.KVO
  • 2.NSNotificationCenter
  • 3.Delegate等
MJRefresh中使用的是KVO的方式监听偏移量:

下面的willMoveToSuperView 方法中传过来的newSuperView 是你实现此功能的UITableView 和 UICollectionView的对象,此方法只在设置tableView的下拉和上提的时候执行一次(或者说只在当前页面初始化的时候执行一次);
此时我们通过 addObserver forKeyPath 的方式监听了ContentOffset的变化

设置偏移量监听
由于我们在上面设置了偏移量的监听,那么当UIScrollView的偏移量变化时,都会执行 observerValueForKeyPath方法
在这里面我们可以做一系列的逻辑判断,比如 刷新状态的变化,一些动画效果什么的(具体的判断就不说了,不然就就偏离了这篇文章的主题)

监听事件的执行
具体的偏移量变化判断暂不讲解;

偏移量逻辑判断方法

step6:

至此,我们基本上就把MJRefresh的下拉刷新的实现的大体流程给过了一遍,以后如果想丰富一下MJRefresh的话,比如增加时间的变化,或者增加GIF图片的效果,我觉得都不是太难的问题了,因为框架已经搭起来了以后想往里面塞什么东西,那就看需求了


最后我们要做的就是 写一个方法去实例化一个header的对象,然后将这个对象赋值给我们的UIScrollView的header属性

实例化一个header的对象
这样就可以实现一个简单的下拉刷新控件

 

这边文章主要讲了一下我们写MJRefresh的思路,没有讲一些具体实现方法

个人认为 编程重要的是思路,是想法,把想法理解透了,以后不管是OC 还是Android 还是Java PHP都是可以用的上的

以上只是个人对MJRefresh的理解,有一些理解不到的地方希望大家多多指教,多多批评


demo下载地址:http://www.code4app.com/thread-10770-1-1.html

转自:http://www.jianshu.com/p/9d5a3c543768

如何写一套下拉刷新的控件?《MJRefresh原理浅析》(附Demo下载地址)的更多相关文章

  1. vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件

    vue10行代码实现上拉翻页加载更多数据,纯手写js实现下拉刷新上拉翻页不引用任何第三方插件/库 一提到移动端的下拉刷新上拉翻页,你可能就会想到iScroll插件,没错iScroll是一个高性能,资源 ...

  2. cocos2d-html5 简易 下拉表单 控件

    刚才在CH5的群里问了问  有没有大侠写过 下拉表单控件啊!  没人鸟窝 ,DZ老师表示非常伤心啊  ,于是乎  自己写一个把 共享给大家. 效果图上一个  仅仅实现了一个最最主要的控件  非常eas ...

  3. Atitit.ui控件---下拉菜单选择控件的实现select html

    Atitit.ui控件---下拉菜单选择控件的实现select   html 1. 调用& model的实现 1 2. -----select.jsp------ 1 1. 调用& m ...

  4. [RN] React Native 仿美团下拉筛选菜单控件

    React Native 仿美团下拉筛选菜单控件 演示效果如下: 使用方法如下: 1.安装 npm install react-native-dropdownmenus --save react-na ...

  5. EasyUI的下拉选择框控件方法被屏蔽处理方式

    1.html标签如下 <div id="selectMap" style="top: 1px;left: 80px;position: absolute;" ...

  6. 扩展自easyui的combo组件的下拉多选控件

    首先上效果图 代码片段: 有需要的朋友微信联系我. 如果这篇文章对您有帮助,您可以打赏我 技术交流QQ群:15129679    

  7. android124 zhihuibeijing 新闻中心-新闻 -北京页签 下拉刷新

    缓存工具类:以url为key,json数据为value, package com.itheima.zhbj52.utils; import com.itheima.zhbj52.global.Glob ...

  8. 指令汇B新闻客户端开发(三) 下拉刷新

    现在我们继续这个新闻客户端的开发,今天分享的是下拉刷新的实现,我们都知道下拉刷新是一个应用很常见也很实用的功能.我这个应用是通过拉ListView来实现刷新的,先看一张刷新的原理图 从图中可知,手指移 ...

  9. android开发(3):列表listview的实现 | 下拉刷新

    APP里面的列表太常用了,系统提供的listview或grideview可以做到.另外,我希望这个列表能够下拉时触发刷新,于是考虑使用封装了这个功能的开源项目,这里介绍这个: https://gith ...

随机推荐

  1. Docker build 安装报错, Could not open requirments file: [Errno 2] No such file or directory:'requirements.txt'

    docker安装教程 https://docs.docker.com/get-started/part2/#build-the-app 相关帖子 https://stackoverflow.com/q ...

  2. 使用Excel调用ABAP系统的函数

    效果:在excel里创建一个按钮,开发一些VB script,可以连接指定的ABAP系统并执行系统里的ABAP function module. 在这里例子里执行ABAP系统的函数TH_USER_LI ...

  3. IOS 计算文字尺寸(UILabel)

    方式1 :普通用法 #define  MJNameFont [UIFont systemFontOfSize:14] /** * 计算文字尺寸 * * @param text 需要计算尺寸的文字 * ...

  4. 2018.7.15 解决css中input输入框点击时去掉外边框方法

    .input_css{ background:no-repeat 0 0 scroll #EEEEEE; border:none; outline:medium; }

  5. Ubuntu下几种常用的文本编辑器

    常见的基于控制台的文本编辑器有以下几种: emacs           综合性的GNU emacs 编辑环境 nano              一个类似于经典的pico的文本编辑器,内置了一个pi ...

  6. 【洛谷P1880】[NOI1995]石子合并

    石子合并 fmax[l][r]表示合并区间[l,r]的最大分值, fmin[l][r]表示合并区间[l,r]的最小分值 for(k l~r-1) fmax[l][r]=max(fmax[l][r],f ...

  7. 共变导数(Covariant Derivative)

    原文链接 导数是指某一点的导数表示了某点上指定函数的变化率. 比如,要确定某物体的速度在某时刻的加速度,就取时间轴上下一时刻的一个微小增量,然后考察速度的增量和时间增量的比值.如果这个比值比较大,说明 ...

  8. Velocity中加载vm文件的三种方式

    Velocity中加载vm文件的三种方式: a.  加载classpath目录下的vm文件 /** * 初始化Velocity引擎 * --VelocityEngine是单例模式,线程安全 * @th ...

  9. AMD、CMD、CommonJs和ES6对比

    一.AMD(异步模块定义) AMD(异步模块定义)是RequireJS在推广过程中对模块定义的规范化产出.AMD是一个概念,RequireJs是对这个概念的实现.比如javascript语言是对ECM ...

  10. EBS并发管理器启动失败,系统暂挂,在重置计数器之前修复管理程序

    今天EBS安装补丁之后,因为停并发管理器的时候,因为关闭EBS应用时,并发管理器没有在前台停止,就直接停了应用服务,导致启动时,并发管理器直接起不来了,使用adcmctl.sh也没有办法启动. 进入系 ...