上一篇MJRefresh源码阅读(一)中介绍了MJRefreshComponent的实现,这篇介绍MJRefreshHeader中的实现。
MJRefreshHeader是继承自MJRefreshComponent,是下拉刷新控件:负责监控用户下拉刷新的状态。在MJRefreshComponent中给UIScrollView的contentSize和congentOffSet属性添加了KVO监听,所以在下拉刷新的时候,contentOffset就会发生变化,然后会调用相应的方法:
[self scrollViewContentSizeDidChange:change];
在MJRefreshHeader中对该方法进行重写
//在该方法中通过UIScrollView的contentOffset偏移的大小和UIScrollView的topInset以及刷新的UIView的height高度的比较来判断出当前处于什么状态,给状态state赋值,而在前面有给手势pan的state添加kvo监听,pan手势取消时state发生变化会调用[self scrollViewPanStateDidChange:change];在子类中重写这个方法进行相应的逻辑处理
- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change {{
[super scrollViewContentOffsetDidChange:change];
// 在刷新的refreshing状态
if (self.state == MJRefreshStateRefreshing) {
[self resetInset];
return;
}
// 跳转到下一个控制器时,contentInset可能会变
_scrollViewOriginalInset = self.scrollView.mj_inset;
// 当前的contentOffset
CGFloat offsetY = self.scrollView.mj_offsetY;
// 头部控件刚好出现的offsetY
CGFloat happenOffsetY = - self.scrollViewOriginalInset.top;
// 如果是向上滚动到看不见头部控件,直接返回
// >= -> >
if (offsetY > happenOffsetY) return;
// 普通 和 即将刷新 的临界点
CGFloat normal2pullingOffsetY = happenOffsetY - self.mj_h;
CGFloat pullingPercent = (happenOffsetY - offsetY) / self.mj_h;
if (self.scrollView.isDragging) { // 如果正在拖拽
self.pullingPercent = pullingPercent;
if (self.state == MJRefreshStateIdle && offsetY < normal2pullingOffsetY) {
// 转为即将刷新状态
self.state = MJRefreshStatePulling;
} else if (self.state == MJRefreshStatePulling && offsetY >= normal2pullingOffsetY) {
// 转为普通状态
self.state = MJRefreshStateIdle;
}
} else if (self.state == MJRefreshStatePulling) {// 即将刷新 && 手松开
// 开始刷新
[self beginRefreshing];
} else if (pullingPercent < 1) {
self.pullingPercent = pullingPercent;
}
}
后面看到在setState方法中,有对刷新时间做了存储,使用的是NSUserDefault
//保存刷新时间
[[NSUserDefaults standardUserDefaults] setObject:[NSDate date] forKey:self.lastUpdatedTimeKey];
[[NSUserDefaults standardUserDefaults] synchronize];
//取出刷新时间
- (NSDate *)lastUpdatedTime
{
return [[NSUserDefaults standardUserDefaults] objectForKey:self.lastUpdatedTimeKey];
}
网友评论