MJRefresh源码框架分析
[self prepare];//在父类initWithFrame方法调用
[self placeSubviews];//在父类layoutSubviews方法调用
类继承:父类定义了方法的基本实现,子类在此基础上进行持续增加,达到复杂功能。与模版方法的区别是没有固定的执行步骤。
//状态设置
- (void)setState:(MJRefreshState)state
//事件监听
- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change{}
- (void)scrollViewContentSizeDidChange:(NSDictionary *)change{}
- (void)scrollViewPanStateDidChange:(NSDictionary *)change{}
- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change{}

- (void)prepare
{
[super prepare]; // 设置key
self.lastUpdatedTimeKey = MJRefreshHeaderLastUpdatedTimeKey; // 设置高度
self.mj_h = MJRefreshHeaderHeight;
} - (void)placeSubviews
{
[super placeSubviews]; // 设置y值(当自己的高度发生改变了,肯定要重新调整Y值,所以放到placeSubviews方法中设置y值)
self.mj_y = - self.mj_h - self.ignoredScrollViewContentInsetTop;
}
- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change
{
[super scrollViewContentOffsetDidChange:change]; // 在刷新的refreshing状态
if (self.state == MJRefreshStateRefreshing) {
// 暂时保留
//My:当NavigationBar从一个页面滑出时,可能被移除页面,其window为nil
if (self.window == nil) return; // sectionheader停留解决
//My:当scrollView向下偏移的距离超过它的contentInset的上间隔时,取距离大的
CGFloat insetT = - self.scrollView.mj_offsetY > _scrollViewOriginalInset.top ? - self.scrollView.mj_offsetY : _scrollViewOriginalInset.top;
//My:当这个距离超过了(刷新控件的高度 + 它的contentInset的上间隔)时,取它们的和值
insetT = insetT > self.mj_h + _scrollViewOriginalInset.top ? self.mj_h + _scrollViewOriginalInset.top : insetT;
//My:将这个合理的最大值,设置到它的contentInset的上间隔上。
self.scrollView.mj_insetT = insetT;
//My:实际露出的刷新空间高
self.insetTDelta = _scrollViewOriginalInset.top - insetT;
return;
} // 跳转到下一个控制器时,contentInset可能会变
_scrollViewOriginalInset = self.scrollView.mj_inset; // 当前的contentOffset
CGFloat offsetY = self.scrollView.mj_offsetY;
// 头部控件刚好出现的offsetY
CGFloat happenOffsetY = - self.scrollViewOriginalInset.top; // 如果是向上滚动到看不见头部控件,直接返回
// >= -> >
if (offsetY > happenOffsetY) return; // 普通 和 即将刷新 的临界点
//My:下拉距离正好是(刷新控件高度+contentInset的上间隔)
CGFloat normal2pullingOffsetY = happenOffsetY - self.mj_h;
//My:露出的高度/总高度
CGFloat pullingPercent = (happenOffsetY - offsetY) / self.mj_h; if (self.scrollView.isDragging) { // 如果正在拖拽
self.pullingPercent = pullingPercent; if (self.state == MJRefreshStateIdle && offsetY < normal2pullingOffsetY) {
//My:下拉度超过临界值 // 转为即将刷新状态
self.state = MJRefreshStatePulling;
} else if (self.state == MJRefreshStatePulling && offsetY >= normal2pullingOffsetY) {
//My:下拉度小于临界值 // 转为普通状态
self.state = MJRefreshStateIdle;
}
} else if (self.state == MJRefreshStatePulling) {
// 即将刷新 && 手松开 // 开始刷新
[self beginRefreshing];
} else if (pullingPercent < ) {
self.pullingPercent = pullingPercent;
}
}
- (void)setState:(MJRefreshState)state
{
MJRefreshCheckState // 根据状态做事情
if (state == MJRefreshStateIdle) {
if (oldState != MJRefreshStateRefreshing) return; // 保存刷新时间
[[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:self.lastUpdatedTimeKey];
[[NSUserDefaults standardUserDefaults] synchronize]; // 恢复inset和offset
[UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{
self.scrollView.mj_insetT += self.insetTDelta; // 自动调整透明度
if (self.isAutomaticallyChangeAlpha) self.alpha = 0.0;
} completion:^(BOOL finished) {
self.pullingPercent = 0.0; if (self.endRefreshingCompletionBlock) {
self.endRefreshingCompletionBlock();
}
}];
} else if (state == MJRefreshStateRefreshing) {
MJRefreshDispatchAsyncOnMainQueue({
[UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{
if (self.scrollView.panGestureRecognizer.state != UIGestureRecognizerStateCancelled) {
CGFloat top = self.scrollViewOriginalInset.top + self.mj_h;
// 增加滚动区域top
self.scrollView.mj_insetT = top;
// 设置滚动位置
CGPoint offset = self.scrollView.contentOffset;
offset.y = -top;
[self.scrollView setContentOffset:offset animated:NO];
}
} completion:^(BOOL finished) {
[self executeRefreshingCallback];
}];
})
}
}
MJRefresh源码框架分析的更多相关文章
- golang 移动应用例子 example/basic 源码框架分析
条件编译 我们在源码中可以看到2个文件: main.go 和 main_x.go 这两个包名都是 package main , 都有 main 函数. 不会冲突么? 答案是不会的, main_x.go ...
- android adb 源码框架分析(2 角色)【转】
本文转载自:http://blog.csdn.net/luansxx/article/details/25203323 角色 l 服务 服务是提供特定功能的实体,接收请求,返回应答是服务直接最表现. ...
- android adb 源码框架分析(1 系统)【转】
本文转载自:http://blog.csdn.net/luansxx/article/details/25203269 ‘ Adb模块包括adb,adbd,源代码都在system/core/adb目录 ...
- JUC同步器框架AbstractQueuedSynchronizer源码图文分析
JUC同步器框架AbstractQueuedSynchronizer源码图文分析 前提 Doug Lea大神在编写JUC(java.util.concurrent)包的时候引入了java.util.c ...
- LinkedHashMap 源码详细分析(JDK1.8)
1. 概述 LinkedHashMap 继承自 HashMap,在 HashMap 基础上,通过维护一条双向链表,解决了 HashMap 不能随时保持遍历顺序和插入顺序一致的问题.除此之外,Linke ...
- 【Orleans开胃菜系列2】连接Connect源码简易分析
[Orleans开胃菜系列2]连接Connect源码简易分析 /** * prism.js Github theme based on GitHub's theme. * @author Sam Cl ...
- RxJava && Agera 从源码简要分析基本调用流程(2)
版权声明:本文由晋中望原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/124 来源:腾云阁 https://www.qclo ...
- FFmpeg的HEVC解码器源码简单分析:概述
===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...
- 自定义View系列教程03--onLayout源码详尽分析
深入探讨Android异步精髓Handler 站在源码的肩膀上全解Scroller工作机制 Android多分辨率适配框架(1)- 核心基础 Android多分辨率适配框架(2)- 原理剖析 Andr ...
随机推荐
- 为某金融企业的IT技术部人员提供基于TFS的软件研发流程介绍
受莫金融企业IT信息技术部的邀请,为该金融企业的某省分公司.地市分公司的IT技术人员提供了一场基于TFS的软件研发流程的技术培训,希望可以借此提高该企业的软件研发.运维水平,同时推动企业软件研发信息化 ...
- TFS 2015 生成不输出任何结果
这是一台用于测试的TFS 2015服务器,其中的数据是通过备份和还原,在使用应用层专用的方式配置出来的. 在配置完成代理服务器以后,运行生成,发现在获取代码之前就停止失败了,并且在生成过程中没有任何结 ...
- winform之combobox
绑定键值对: ArrayList mylist = new ArrayList(); mylist.Add(new DictionaryEntry("WinFormURL", &q ...
- Spring Boot - Spring Data
使用JPA 虽然JPA是一个标准,但spring中一般就是使用hibernate实现的 使用JPA(Java Persistence API,Java持久化API,是个规范,其实是借助Hibernat ...
- 关于STM32位带操作随笔
以前在学习STM32时候关注过STM32的位带操作,那时候只是知道位带是啥,用来干嘛用,说句心里话,并没有深入去学习,知其然而不知其所以然.但一直在心中存在疑惑,故今日便仔细看了一下,写下心得供日后参 ...
- C#跨线程操作UI
WPF启动调度器 : Dispatcher.Invoke(new Action(() => { //你的代码 }));
- UWP开发---通过委托跨页面导航
-前言 做过.Net开发的都了解,当二级窗口操作主窗口的控件时通常用委托的方式.那么在UWP开发中,常常会遇到MainPage的二级Frame里面的内容去操作MainPage的导航跳转,具体看下图: ...
- Flask系列01--flask认识, 启动, 响应
一. 四款python web框架简单总结 Django : 优点 - 大而全所有组件都是有组织内部开发高度定制化 教科书级别的框架 缺点 - 浪费资源,请求的时候需要的资源较高 Flask : 优势 ...
- Redux其实很简单(原理篇)
在这一篇文章中,笔者将带大家编写一个完整的Redux,深度剖析Redux的方方面面,读完本篇文章后,大家对Redux会有一个深刻的认识. 核心API 这套代码是笔者阅读完Redux源码,理解其设计思路 ...
- 任务查询系统(cqoi2015,bzoj3932)(主席树)
最近实验室正在为其管理的超级计算机编制一套任务管理系统,而你被安排完成其中的查询部分.超级计算机中的 任务用三元组\((S_i,E_i,P_i)\)描述,\((S_i,E_i,P_i)\)表示任务从第 ...