MAGI的专栏 2018-05-18
在上一篇《iOS ScrollView 下拉放大》已经介绍了基本的下拉放大,结下来再加上下拉刷新
定义下拉刷新状态
typedef enum {
RefreshStateIdle,
RefreshStatePullRefresh,
RefreshStateReadyRefresh,
RefreshStateRefreshing
} RefreshState;定义下拉刷新需使用的变量
{
// Refresh
UILabel *_refreshLabel;
RefreshState _refreshState;
CGFloat _refreshHeight;
}下拉刷新的实现是在下拉刷的新阀值detal小于下拉放大阀值alpha的基础上进行的,接下来就初始化下拉刷新的变量了
_refreshState = RefreshStateIdle;
_refreshHeight = ;
_refreshLabel = [[UILabel alloc] initWithFrame:CGRectMake(, -
_refreshHeight, self.view.bounds.size.width, _refreshHeight)];
_refreshLabel.textAlignment = NSTextAlignmentCenter;
_refreshLabel.textColor = [UIColor redColor];
_refreshLabel.text = @"刷新...";
[self.view addSubview:_refreshLabel];然后改造ScrollView代理方法了,在处理下拉放大的过程中同时处理下拉刷新
#pragma mark - ScrollView Delegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (_refreshState == RefreshStateRefreshing) {
return;
}
CGFloat offsetY = scrollView.contentOffset.y;
NSLog(@"offsetY: %f",offsetY);
CGFloat top = scrollView.contentInset.top;
if (!_zoomIn) {
if (offsetY < -top) { // 下拉
CGRect frame = _zoomView.frame;
frame.origin.y = offsetY;
frame.size.height = -offsetY;
_zoomView.frame = frame;
// 处理下拉
if (_refreshState != RefreshStateRefreshing && !_decelerating) {
frame = _refreshLabel.frame;
frame.origin.y = -offsetY - top;
_refreshLabel.frame = frame;
if ((-offsetY - top) < _refreshHeight) {
[self setRefreshState:RefreshStatePullRefresh];
} else {
[self setRefreshState:RefreshStateReadyRefresh];
}
}
if (!_decelerating && -offsetY > 1.9 * _zoomHeight) {
[self setRefreshState:RefreshStateIdle];
frame.origin.y = -_refreshHeight;
_refreshLabel.frame = frame;
scrollView.contentInset = UIEdgeInsetsMake(scrollView.bounds.size.height, , , );
frame.origin.y = -scrollView.bounds.size.height;
frame.size.height = scrollView.bounds.size.height;
_zoomView.frame = frame;
_zoomIn = YES;
scrollView.contentSize = CGSizeMake(, ); // 使上拉有弹簧效果
}
}
} else { // 上拉
if (!_decelerating && (offsetY + top) / top > 0.3) {
scrollView.contentInset = UIEdgeInsetsMake(_zoomHeight, , , );
CGRect frame = _zoomView.frame;
frame.origin.y = -_zoomHeight;
frame.size.height = _zoomHeight;
_zoomView.frame = frame;
_zoomIn = NO;
scrollView.contentSize = CGSizeMake(, _contentSize.height); // 恢复正常
}
}
}
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView {
_decelerating = YES;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
_decelerating = NO;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
if (_refreshState == RefreshStateRefreshing) {
return;
}
CGRect frame = _refreshLabel.frame;
if (_refreshState == RefreshStateReadyRefresh) {
[self setRefreshState:RefreshStateRefreshing];
frame.origin.y = ;
} else {
[self setRefreshState:RefreshStateIdle];
frame.origin.y = -_refreshHeight;
}
_refreshLabel.frame = frame;
}
#pragma mark - Refresh
- (void)setRefreshState:(RefreshState)state {
_refreshState = state;
if (_refreshState == RefreshStateIdle) {
_refreshLabel.text = @"下拉刷新";
} else if (_refreshState == RefreshStatePullRefresh) {
_refreshLabel.text = @"下拉刷新";
} else if (_refreshState == RefreshStateReadyRefresh) {
_refreshLabel.text = @"松开刷新";
} else if (_refreshState == RefreshStateRefreshing) {
_refreshLabel.text = @"刷新...";
[self loadData];
}
}处理滑动的过程中,如果当前正在刷新那么立即返回。下拉过程中根据offsetY值判断到达阀值,在到达刷新阀值detal后并且没有达到放大阀值alpha,那么松手的时候就进入刷新状态,没有达到下拉刷新阀值detal就松手的情况下就恢复正常。如果在达到下拉刷新阀值detal后继续下拉到达放大阀值,那么就将刷新状态置为idle,同时隐藏刷新View,做放大操作。
当然,刷新完成后还要报告刷新完成,以处理刷新View
#pragma mark - Load Data
- (void)loadData {
__weak typeof(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(0, 0), ^{
sleep(5);
dispatch_async(dispatch_get_main_queue(), ^{
if (weakSelf) {
__strong typeof(weakSelf) strongSelf = weakSelf;
[strongSelf refreshFinish];
}
});
});
}
- (void)refreshFinish {
[self setRefreshState:RefreshStateIdle];
CGRect frame = _refreshLabel.frame;
frame.origin.y = -_refreshHeight;
_refreshLabel.frame = frame;
}