forked from 151283250/MJRefresh
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMJRefreshFooterView.m
196 lines (166 loc) · 5.51 KB
/
MJRefreshFooterView.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
//
// 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;
}
@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)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;
if (MJRefreshStateRefreshing == oldState && deltaH > 0 && !_withoutIdle) {
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:
{
_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