MJRefresh 下拉刷新源码分析

这里写图片描述

MJRefreshComponent父类中添加了对scrollview的观察者
监听 scrollViewContentOffset的变化
通过子类当contentOffset变化时,设置状态
具体变化为,
offsetY -64 距scrollview的原始位置的Y向下了64
Inset 64
普通和即将刷新的连接点是118记 inset - self.mj_h
pullingPercent = offset - insetY / self.mj_h

在拖拽状态下只切换即将刷新和普通刷新两种状态
在结束拖拽后才执行是具体的刷新还是只设置pullingPercent
如果拖拽结束是开始刷新,则会掉用MJRefreshComponent的
beginRefreshing状态
在这个刷新状态下,将MJRefreshStatePulling状态转为
MJRefreshStateRefreshing,(这个状态下也有可能是在结束上一个
controller的MJRefreshStateIdle这个状态,所以要先把下一个controller
的这个状态转为MJRefreshStateWillRefresh状态.)当把状态转为
self.state = MJRefreshStateRefreshing时,在setState方法中首先
在component上是先给主线程中添加一个layout以便设置为state后调用
layoutSubview再在MJRefresHeader中
改变self.scrollview的contentInset 从而引起contentOffset也变为-contentInset
当变化了contentInset后,执行刷新的block,调用刚开始赋值的block,执行
[tableView.mj_header endRefreshing];
在结束刷新中,将状态转为MJRefreshStateIdle,当状态变化时
会调用MJRefreshNormalHeader类中的setState然后会调用
父类的setState直到调用了MJRefreshHeader中的setState,这时候在次函数中
设置self.scrollView.contentInset = 64,就可以了,
一旦设置了self.scrollView.contentInset = 64会引起self.scrollView.contentOffset.top = -64
恢复到正常状态,在完成的block中执行结束刷新的block

重点都在MJRefreshCompnent和MJRefreshHeader这两个类中


setNeedsDisplay会调用(drawRect)方便绘图和setNeedsLayout会调用(layoutSubViews)方便出来数据

tableView的setMj_header:中有[self insertSubview:mj_header atIndex:0]触发子类
MJRefreshNormalHeader类进行willMoveToSuperview


mj调用prepare,setState:,placeSubviews的过程
先用component初始化调用自己的normal的prepare,
然后自己normal的prepare方法中调用[super prepare]中一层层调用父类.

component中的
prepare :设置背景颜色,和autoresizingMake
setState:_state从0赋值为1即MJRefreshStateIdle, 2[self setNeedsLayout]加入主队列的目的是等setState:方法调用完毕、设置完文字后再去布局子控件
placeSubviews:{}
header 中的
prepare:设置lastUpdatedTimeKey(设置最后更新时间),及给label赋值,高度mj_h
setState: 第一次返回
placeSubviews: self.mj_y = - self.mj_h - self.ignoredScrollViewContentInsetTop;

stateHeader中的
prepare: self.labelLeftInset(文字距左边箭头距离25),
下拉可以刷新:MJRefreshStateIdle
松开立即刷新:MJRefreshStatePulling
正在刷新数据中…:MJRefreshStateRefreshing
setState:设置stateLabel.text,重新设置self.lastUpdatedTimeKey,执行setlastUpdatedTimeKey时候给label赋值了
placeSubviews: stateLable和lastUpdatedTimeLabel的frame
normal:
prepare: 1 UIActivityIndicatorViewStyleGray
2 标记layout 记setNeedsLayout
setState: [self addSubview loadingView] [self addSubview self.arrowView]
placeSubviews:箭头和圆圈的frame
***********************************************************************8
MJRefreshComponent.h:
成员变量:
_scrollView,
_scrollViewOriginalInset;
属性:
refreshingTarget
refreshingAction
三个block属性 :
refreshingBlock,
beginRefreshingCompletionBlock,
endRefreshingCompletionBlock,
refreshing,
state(MJRefreshState),
scrollViewOriginalInset,
scrollView,(父控件)
pulliingPercent,(交给子类重写)
automaticallyChangeAlpha,

方法:
1:setRefreshingTarget:refreshingAction:
2:executeRefreshingCallback;(触发回调,交给子类去调用)
3:beginRefreshing,
4:beginRefreshingWithCompletionBlock:(void(^)(void))completionBlock;
5:endRefreshing,
6:endRefreshingWithCompletionBlock:(void(^)(void))completionBlock;

7:prepare,(交给子类实现)
8:placeSubViews,(摆放子控件frame)
9:scrollViewContentOffsetDidChange:
10:scrollViewContentSizeDidChange:
11:scrollViewPanStateDidChange:

MJRefreshComponent.m:
属性:
pan,
方法:
initWithFrame中两件事情
1 [self prepare];
2 self.state = MJRefreshStateIdle;

layoutSubviews中一件事情
    1 [self placeSubViews];
    2 [super layoutSubviews];
willMoveToSuperview中设置
    1 self.mj_w
    2 self.mj_x
    3 _scrollView = newSuperView
    4:_scrollViewOriginalInset = _scrollView.mj_inset
    5:添加监听 contentOffset,contentSize,PanState
drawRect:
    1 if state == MJRefreshStateWillRefresh {state = refreshing}
setState中两件事情
    1 _state = state,
    2 [self setNeedsLayout],
beginRefreshing
    1 self.alpha = 1.0,
    2 self.pullingPercent = 1.0,
    3:self.state = refreshing,

UILabel(MJRefresh)
方法
mj_label,
mj_textWith,

MJRefreshHeaderr中
属性:
lastUpdatedTimeKey
lastUpdatedTime
ignoredScrollViewContentInsetTop
insetTDelta
方法:
- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change
重写父类方法
- (void)setState:(MJRefreshState)state
- (void)placeSubviews
- (void)prepare

MJRefreshStateHeader中
属性:
lastUpdatedTimeLabel,
stateLabel,
labelLeftInset,
lastUpdatedTimeText(block)
stateTitles(NSMutableDictionary)(所有状态对应的文字)
方法:
setTitle:forState
重写父类方法
- (void)setState:(MJRefreshState)state
- (void)placeSubviews
- (void)prepare

MJRefreshNormalHeader中
属性:
arrowView,
activityIndicatorViewStyle,
loadingView,
方法:
重写父类方法
- (void)setState:(MJRefreshState)state
- (void)placeSubviews
- (void)prepare

isRefreshing
{state == Refreshing willRefresh}

猜你喜欢

转载自blog.csdn.net/u012581760/article/details/81633122
今日推荐