一句话回答
开始刷新:
通过KVO,监听UIScrollView的contentOffset属性,拖动到达临界点时,切换刷新状态,执行刷新操作
添加监听代码
- (void)addObservers {
NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
[self.scrollView addObserver:self forKeyPath:MJRefreshKeyPathContentOffset options:options context:nil];
[self.scrollView addObserver:self forKeyPath:MJRefreshKeyPathContentSize options:options context:nil];
self.pan = self.scrollView.panGestureRecognizer;
[self.pan addObserver:self forKeyPath:MJRefreshKeyPathPanState options:options context:nil];
[NSNotificationCenter.defaultCenter addObserver:self selector: @selector(i18nDidChange) name:MJRefreshDidChangeLanguageNotification object:MJRefreshConfig.defaultConfig];
}
切换刷新状态,执行刷新操作 (MJRefreshHeader.m 文件中)
- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change
{
...
} else if (self.state == MJRefreshStatePulling) {// 即将刷新 && 手松开
// 开始刷新
[self beginRefreshing];
}
...
}
- (void)executeRefreshingCallback {
执行开发者一开始设置好的 block
if (self.refreshingBlock) {
self.refreshingBlock();
}
...
}
停止刷新: 刷新成功后,手动调用 endRefreshing 函数,结束刷新动作,还原inset和offset
其他要知道的地方
默认情况下,MJRefresh 添加到 scrollview 之后,然后 scrollview 的起始 y 会设置为负数,这样在「不下拉」的时候就看不到,下拉后通过增大 contentInset,相当于把 scrollview 往下挤。刷新完成,再把 contentInset 设置回去,达到回弹的效果。
- (void)headerRefreshingAction {
CGFloat top = self.scrollViewOriginalInset.top + self.mj_h;
...
CGRect bounds = self.scrollView.bounds;
bounds.origin.y = -top;
通过动画设置起始 y
[self.scrollView.layer addAnimation:boundsAnimation forKey:MJRefreshHeaderRefreshingBoundsKey];
}