123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- //
- // MJRefreshBackFooter.m
- // MJRefreshExample
- //
- // Created by MJ Lee on 15/4/24.
- // Copyright (c) 2015年 小码哥. All rights reserved.
- //
- #import "MJRefreshBackFooter.h"
- @interface MJRefreshBackFooter()
- @property (assign, nonatomic) NSInteger lastRefreshCount;
- @property (assign, nonatomic) CGFloat lastBottomDelta;
- @end
- @implementation MJRefreshBackFooter
- #pragma mark - 初始化
- - (void)willMoveToSuperview:(UIView *)newSuperview
- {
- [super willMoveToSuperview:newSuperview];
-
- [self scrollViewContentSizeDidChange:nil];
- }
- #pragma mark - 实现父类的方法
- - (void)scrollViewContentOffsetDidChange:(NSDictionary *)change
- {
- [super scrollViewContentOffsetDidChange:change];
-
- // 如果正在刷新,直接返回
- if (self.state == MJRefreshStateRefreshing) return;
-
- _scrollViewOriginalInset = self.scrollView.contentInset;
-
- // 当前的contentOffset
- CGFloat currentOffsetY = self.scrollView.mj_offsetY;
- // 尾部控件刚好出现的offsetY
- CGFloat happenOffsetY = [self happenOffsetY];
- // 如果是向下滚动到看不见尾部控件,直接返回
- if (currentOffsetY <= happenOffsetY) return;
-
- CGFloat pullingPercent = (currentOffsetY - happenOffsetY) / self.mj_h;
-
- // 如果已全部加载,仅设置pullingPercent,然后返回
- if (self.state == MJRefreshStateNoMoreData) {
- self.pullingPercent = pullingPercent;
- return;
- }
-
- if (self.scrollView.isDragging) {
- self.pullingPercent = pullingPercent;
- // 普通 和 即将刷新 的临界点
- CGFloat normal2pullingOffsetY = happenOffsetY + self.mj_h;
-
- if (self.state == MJRefreshStateIdle && currentOffsetY > normal2pullingOffsetY) {
- // 转为即将刷新状态
- self.state = MJRefreshStatePulling;
- } else if (self.state == MJRefreshStatePulling && currentOffsetY <= normal2pullingOffsetY) {
- // 转为普通状态
- self.state = MJRefreshStateIdle;
- }
- } else if (self.state == MJRefreshStatePulling) {// 即将刷新 && 手松开
- // 开始刷新
- [self beginRefreshing];
- } else if (pullingPercent < 1) {
- self.pullingPercent = pullingPercent;
- }
- }
- - (void)scrollViewContentSizeDidChange:(NSDictionary *)change
- {
- [super scrollViewContentSizeDidChange:change];
-
- // 内容的高度
- CGFloat contentHeight = self.scrollView.mj_contentH + self.ignoredScrollViewContentInsetBottom;
- // 表格的高度
- CGFloat scrollHeight = self.scrollView.mj_h - self.scrollViewOriginalInset.top - self.scrollViewOriginalInset.bottom + self.ignoredScrollViewContentInsetBottom;
- // 设置位置和尺寸
- self.mj_y = MAX(contentHeight, scrollHeight);
- }
- - (void)setState:(MJRefreshState)state
- {
- MJRefreshCheckState
-
- // 根据状态来设置属性
- if (state == MJRefreshStateNoMoreData || state == MJRefreshStateIdle) {
- // 刷新完毕
- if (MJRefreshStateRefreshing == oldState) {
- [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{
- self.scrollView.mj_insetB -= self.lastBottomDelta;
-
- // 自动调整透明度
- if (self.isAutomaticallyChangeAlpha) self.alpha = 0.0;
- } completion:^(BOOL finished) {
- self.pullingPercent = 0.0;
- }];
- }
-
- CGFloat deltaH = [self heightForContentBreakView];
- // 刚刷新完毕
- if (MJRefreshStateRefreshing == oldState && deltaH > 0 && self.scrollView.mj_totalDataCount != self.lastRefreshCount) {
- self.scrollView.mj_offsetY = self.scrollView.mj_offsetY;
- }
- } else if (state == MJRefreshStateRefreshing) {
- // 记录刷新前的数量
- self.lastRefreshCount = self.scrollView.mj_totalDataCount;
-
- [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{
- CGFloat bottom = self.mj_h + self.scrollViewOriginalInset.bottom;
- CGFloat deltaH = [self heightForContentBreakView];
- if (deltaH < 0) { // 如果内容高度小于view的高度
- bottom -= deltaH;
- }
- self.lastBottomDelta = bottom - self.scrollView.mj_insetB;
- self.scrollView.mj_insetB = bottom;
- self.scrollView.mj_offsetY = [self happenOffsetY] + self.mj_h;
- } completion:^(BOOL finished) {
- [self executeRefreshingCallback];
- }];
- }
- }
- #pragma mark - 公共方法
- - (void)endRefreshing
- {
- if ([self.scrollView isKindOfClass:[UICollectionView class]]) {
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- [super endRefreshing];
- });
- } else {
- [super endRefreshing];
- }
- }
- - (void)noticeNoMoreData
- {
- if ([self.scrollView isKindOfClass:[UICollectionView class]]) {
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- [super noticeNoMoreData];
- });
- } else {
- [super noticeNoMoreData];
- }
- }
- #pragma mark - 私有方法
- #pragma mark 获得scrollView的内容 超出 view 的高度
- - (CGFloat)heightForContentBreakView
- {
- CGFloat h = self.scrollView.frame.size.height - self.scrollViewOriginalInset.bottom - self.scrollViewOriginalInset.top;
- return self.scrollView.contentSize.height - h;
- }
- #pragma mark 刚好看到上拉刷新控件时的contentOffset.y
- - (CGFloat)happenOffsetY
- {
- CGFloat deltaH = [self heightForContentBreakView];
- if (deltaH > 0) {
- return deltaH - self.scrollViewOriginalInset.top;
- } else {
- return - self.scrollViewOriginalInset.top;
- }
- }
- @end
|