123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- //
- // MJRefreshFooterView.m
- // MJRefresh
- //
- // Created by mj on 13-2-26.
- // Copyright (c) 2013年 itcast. All rights reserved.
- // 上拉加载更多
- #import "MJRefreshFooterView.h"
- #import "MJRefreshConst.h"
- @interface MJRefreshFooterView()
- //{
- // BOOL _withoutIdle;
- //}
- {
- int _lastRefreshCount;
- }
- @end
- @implementation MJRefreshFooterView
- + (instancetype)footer
- {
- return [[MJRefreshFooterView alloc] init];
- }
- #pragma mark - 初始化
- - (instancetype)initWithFrame:(CGRect)frame {
- if (self = [super initWithFrame: frame]) {
- // 移除刷新时间
- [_lastUpdateTimeLabel removeFromSuperview];
- _lastUpdateTimeLabel = nil;
- }
- return self;
- }
- -(void)dealloc{
- NSLog(@"MJRefreshFooterView.dealloc");
- }
- - (void)setFrame:(CGRect)frame
- {
- [super setFrame:frame];
-
- CGFloat h = frame.size.height;
- if (_statusLabel.center.y != h * 0.5) {
- CGFloat w = frame.size.width;
- _statusLabel.center = CGPointMake(w * 0.5, h * 0.5);
- }
- }
- #pragma mark - UIScrollView相关
- #pragma mark 重写设置ScrollView
- - (void)setScrollView:(UIScrollView *)scrollView
- {
- // 1.移除以前的监听器
- [_scrollView removeObserver:self forKeyPath:MJRefreshContentSize context:nil];
- // 2.监听contentSize
- [scrollView addObserver:self forKeyPath:MJRefreshContentSize options:NSKeyValueObservingOptionNew context:nil];
-
- // 3.父类的方法
- [super setScrollView:scrollView];
-
- // 4.重新调整frame
- [self adjustFrame];
- }
- #pragma mark 监听UIScrollView的属性
- - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
- {
- [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
-
- if (!self.userInteractionEnabled || self.alpha <= 0.01 || self.hidden) return;
-
- if ([MJRefreshContentSize isEqualToString:keyPath]) {
- [self adjustFrame];
- }
- }
- #pragma mark 重写调整frame
- - (void)adjustFrame
- {
- // 内容的高度
- CGFloat contentHeight = _scrollView.contentSize.height;
- // 表格的高度
- CGFloat scrollHeight = _scrollView.frame.size.height - _scrollViewInitInset.top - _scrollViewInitInset.bottom;
- CGFloat y = MAX(contentHeight, scrollHeight);
- // 设置边框
- self.frame = CGRectMake(0, y, _scrollView.frame.size.width, MJRefreshViewHeight);
- }
- #pragma mark - 状态相关
- #pragma mark 设置状态
- - (void)setState:(MJRefreshState)state
- {
- if (_state == state) return;
- MJRefreshState oldState = _state;
-
- [super setState:state];
-
- switch (state)
- {
- case MJRefreshStatePulling:
- {
- _statusLabel.text = MJRefreshFooterReleaseToRefresh;
-
- [UIView animateWithDuration:MJRefreshAnimationDuration animations:^{
- _arrowImage.transform = CGAffineTransformIdentity;
- UIEdgeInsets inset = _scrollView.contentInset;
- inset.bottom = _scrollViewInitInset.bottom;
- _scrollView.contentInset = inset;
- }];
- break;
- }
-
- case MJRefreshStateNormal:
- {
- _statusLabel.text = MJRefreshFooterPullToRefresh;
-
- // 刚刷新完毕
- CGFloat animDuration = MJRefreshAnimationDuration;
- CGFloat deltaH = [self contentBreakView];
- CGPoint tempOffset;
-
- int currentCount = [self totalDataCountInScrollView];
- if (MJRefreshStateRefreshing == oldState && deltaH > 0 && currentCount != _lastRefreshCount) {
- tempOffset = _scrollView.contentOffset;
- animDuration = 0;
- }
-
- [UIView animateWithDuration:animDuration animations:^{
- _arrowImage.transform = CGAffineTransformMakeRotation(M_PI);
- UIEdgeInsets inset = _scrollView.contentInset;
- inset.bottom = _scrollViewInitInset.bottom;
- _scrollView.contentInset = inset;
- }];
-
- if (animDuration == 0) {
- _scrollView.contentOffset = tempOffset;
- }
- break;
- }
-
- case MJRefreshStateRefreshing:
- {
- // 记录刷新前的数量
- _lastRefreshCount = [self totalDataCountInScrollView];
-
- _statusLabel.text = MJRefreshFooterRefreshing;
- _arrowImage.transform = CGAffineTransformMakeRotation(M_PI);
- [UIView animateWithDuration:MJRefreshAnimationDuration animations:^{
- UIEdgeInsets inset = _scrollView.contentInset;
- CGFloat bottom = MJRefreshViewHeight + _scrollViewInitInset.bottom;
- CGFloat deltaH = [self contentBreakView];
- if (deltaH < 0) { // 如果内容高度小于view的高度
- bottom -= deltaH;
- }
- inset.bottom = bottom;
- _scrollView.contentInset = inset;
- }];
- break;
- }
-
- default:
- break;
- }
- }
- //- (void)endRefreshingWithoutIdle
- //{
- // _withoutIdle = YES;
- // [self endRefreshing];
- // _withoutIdle = NO;
- //}
- #pragma mark 获得scrollView的内容 超出 view 的高度
- - (CGFloat)contentBreakView
- {
- CGFloat h = _scrollView.frame.size.height - _scrollViewInitInset.bottom - _scrollViewInitInset.top;
- return _scrollView.contentSize.height - h;
- }
- #pragma mark - 在父类中用得上
- // 合理的Y值(刚好看到上拉刷新控件时的contentOffset.y,取相反数)
- - (CGFloat)validY
- {
- CGFloat deltaH = [self contentBreakView];
- if (deltaH > 0) {
- return deltaH -_scrollViewInitInset.top;
- } else {
- return -_scrollViewInitInset.top;
- }
- }
- // view的类型
- - (int)viewType
- {
- return MJRefreshViewTypeFooter;
- }
- - (void)free
- {
- [super free];
- [_scrollView removeObserver:self forKeyPath:MJRefreshContentSize];
- }
- @end
|