iOS开发-自定义下拉刷新控件PullDownRefreshView
在开发过程中,有时候需要自定义下拉刷新控件,这时候我们就需要自定义PullDownRefreshView。
PullDownRefreshView是在UIScrollView上。
在下拉刷新过程中,需要实现UIScrollView的delegate的相关方法
// 拖动过程中
三个方法调用顺序
在下拉过程中显示,我们需要将refreshView初始化
- (SDPullDownRefreshView *)refreshView {
if (!_refreshView) {
_refreshView = [[SDPullDownRefreshView alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth([UIScreen mainScreen].bounds), 80)];
}
return _refreshView;
}
配置下拉刷新
- (void)configRefresh {
[self.refreshView setupWithOwner:self.noticationView.tableView delegate:self];
}
实现UIScrollView的Delegate的相关方法
- (void)pullDownRefreshDidFinish {
[self performSelector:@selector(stop) withObject:nil afterDelay:1];
}
- (void)stopLoading {
[self.refreshView stopLoading];
}
- (void)stop {
[self stopLoading];
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
[self.refreshView scrollViewWillBeginDragging:scrollView];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
[self.refreshView scrollViewDidScroll:scrollView];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
[self.refreshView scrollViewDidEndDragging:scrollView willDecelerate:decelerate];
}
整体SDPullDownRefreshView的完整代码
SDPullDownRefreshView.h
#import
@protocol SDPullDownRefreshViewDelegate;
@interface SDPullDownRefreshView : UIView {
BOOL isDragging;
BOOL isLoading;
}
@property (nonatomic, weak) id delegate;
@property (nonatomic, weak) UIScrollView *owner;
@property (nonatomic, strong) UILabel *refreshLabel;
@property (nonatomic, strong) UIActivityIndicatorView *refreshSpinner;
- (void)setupWithOwner:(UIScrollView *)owner delegate:(id)delegate;
- (void)startLoading;
- (void)stopLoading;
// 拖动过程中
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
@end
@protocol SDPullDownRefreshViewDelegate
- (void)pullDownRefreshDidFinish;
@end
SDPullDownRefreshView.m
#import "SDPullDownRefreshView.h"
#define REFRESH_PULL_UP_STATUS @"下拉可以回到上面"
#define REFRESH_RELEASED_STATUS @"可以松开了"
// 加载中
#define REFRESH_LOADING_STATUS @""
#define REFRESHER_HEIGHT 50.0f
@interface SDPullDownRefreshView ()
@end
@implementation SDPullDownRefreshView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
self.clipsToBounds = YES;
self.refreshLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, REFRESHER_HEIGHT)];
self.refreshLabel.backgroundColor = [UIColor clearColor];
self.refreshLabel.font = [UIFont boldSystemFontOfSize:12.0];
self.refreshLabel.textAlignment = NSTextAlignmentCenter;
self.refreshSpinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
self.refreshSpinner.frame = CGRectMake((frame.size.width - 20)/2, (REFRESHER_HEIGHT - 20)/2, 20, 20);
self.refreshSpinner.hidesWhenStopped = YES;
[self addSubview:self.refreshLabel];
[self addSubview:self.refreshSpinner];
}
return self;
}
- (void)layout:(CGPoint)offset {
if (offset.y < 0) {
[self setFrame:CGRectMake(0, 0 - REFRESHER_HEIGHT, self.frame.size.width, REFRESHER_HEIGHT)];
self.refreshLabel.frame = CGRectMake(0, 0, self.frame.size.width, REFRESHER_HEIGHT);
self.refreshSpinner.frame = CGRectMake((self.frame.size.width - 20)/2, (REFRESHER_HEIGHT - 20)/2, 20, 20);
} else {
[self setFrame:CGRectMake(0, -REFRESHER_HEIGHT, self.frame.size.width, 0)];
self.refreshLabel.frame = CGRectMake(0, 0, self.frame.size.width, REFRESHER_HEIGHT);
self.refreshSpinner.frame = CGRectMake((self.frame.size.width - 20)/2, (REFRESHER_HEIGHT - 20)/2, 20, 20);
}
}
- (void)setupWithOwner:(UIScrollView *)owner delegate:(id)delegate {
self.owner = owner;
self.delegate = delegate;
[_owner addSubview:self];
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
if (isLoading) {
return;
}
isDragging = YES;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGPoint offset = scrollView.contentOffset;
[self layout:offset];
if (isLoading && offset.y > 0) {
return;
}
if (isDragging && offset.y <= 0 ) {
[self.refreshSpinner stopAnimating];
// Update the arrow direction and label
if (scrollView.contentOffset.y <= -REFRESHER_HEIGHT) {
// User is scrolling above the header
self.refreshLabel.text = REFRESH_RELEASED_STATUS;
} else {
// User is scrolling somewhere within the header
self.refreshLabel.text = REFRESH_PULL_UP_STATUS;
}
}
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
if (isLoading) return;
isDragging = NO;
// 上拉刷新
if(scrollView.contentOffset.y <= -REFRESHER_HEIGHT){
[self startLoading];
}
}
- (void)startLoading
{
if (isLoading) {
return;
}
isLoading = YES;
UIEdgeInsets contentInset = self.owner.contentInset;
contentInset.top = REFRESHER_HEIGHT;
self.refreshLabel.text = REFRESH_LOADING_STATUS;
[UIView animateWithDuration:0.25 animations:^{
self.owner.contentInset = contentInset;
[self.refreshSpinner startAnimating];
} completion:^(BOOL finished) {
// Refresh action!
if ([self.delegate respondsToSelector:@selector(pullDownRefreshDidFinish)]) {
[self.delegate performSelector:@selector(pullDownRefreshDidFinish) withObject:nil];
}
}];
}
- (void)stopLoading {
isLoading = NO;
UIEdgeInsets contentInset = self.owner.contentInset;
contentInset.top = 0.0;
[UIView animateWithDuration:0.15 animations:^{
self.owner.contentInset = contentInset;
} completion:^(BOOL finished) {
// Reset the header
self.refreshLabel.text = REFRESH_PULL_UP_STATUS;
[self setFrame:CGRectMake(0, -REFRESHER_HEIGHT, self.frame.size.width, 0)];
[self.refreshSpinner stopAnimating];
}];
}
@end
iOS开发-自定义下拉刷新控件PullDownRefreshView
学习记录,每天不停进步。