首先自定义一个UIRefreshControl名字叫做NewRefreshControl,在UITableViewController中将它的refreshControl设置成自定义的refreshControl,并且为refreshControl添加监听事件.
- (void)viewDidLoad {
[super viewDidLoad];
self.refreshControl = [[NewRefreshControl alloc]init];
[self.refreshControl addTarget:self action:@selector(reloadData) forControlEvents:UIControlEventValueChanged];
}
然后自定义一个视图名字叫做NewRefreshView
将NewRefreshView添加到NewRefreshControl中并且设置好约束
[self addSubview:self.refreshView];
//设置约束
self.refreshView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *centerX = [NSLayoutConstraint constraintWithItem:self.refreshView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0];
NSLayoutConstraint *width = [NSLayoutConstraint constraintWithItem:self.refreshView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:160];
NSLayoutConstraint *height = [NSLayoutConstraint constraintWithItem:self.refreshView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:60];
[self addConstraint:centerX];
[self.refreshView addConstraint:width];
[self.refreshView addConstraint:height];
隐藏refreshControl自带的刷新视图,并且使用KVO监听refreshControl的frame
//隐藏菊花
self.tintColor = [UIColor clearColor];
//KVO 监听refreshControl的frame
[self addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
在KVO的回调方法中,当下拉的时候也就是refreshControl的frame改变的时候让箭头翻转.当刷新数据的时候隐藏下拉刷新视图并且显示正在加载的视图
//记录是否翻转
@property(nonatomic,assign)BOOL isTurn;
//记录是否正在加载数据
@property(nonatomic,assign)BOOL isLoading;
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
//当刷新数据的时候隐藏下拉加载视图并且显示正在加载的视图
if (self.isRefreshing && !self.isLoading) {
self.refreshView.pullView.hidden = YES;
//数据加载的动画
[self.refreshView loadingImageViewAnimation];
self.isLoading = YES;
}
//当下拉的时候让箭头翻转(这里自定义的refreshView的高度是60)
if (self.frame.origin.y < -60 && !self.isTurn) {
NSLog(@"翻");
//箭头翻转动画
[self.refreshView pullImageViewAnimation];
self.isTurn = YES;
}else if(self.frame.origin.y > -60 && self.isTurn){
NSLog(@"翻回来");
[self.refreshView pullImageViewAnimation];
self.isTurn = NO;
}
}
- (void)dealloc{
[self removeObserver:self forKeyPath:@"frame"];
}
在自定义的refreshView中实现箭头翻转动画和视图加载动画
#import "NewRefreshView.h"
@implementation NewRefreshView
//箭头翻转动画
- (void)pullImageViewAnimation{
[UIView animateWithDuration:1 animations:^{
self.pullImageView.transform = CGAffineTransformRotate(self.pullImageView.transform, M_PI);
}];
}
//数据加载动画
- (void)loadingImageViewAnimation{
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
animation.toValue = @(2 * M_PI);
animation.duration = 2;
animation.removedOnCompletion = NO;
animation.repeatCount = MAXFLOAT;
[self.loadingImageView.layer addAnimation:animation forKey:nil];
}
@end
最后重写自定义refreshControl的endRefreshing方法
- (void)endRefreshing{
[super endRefreshing];
self.refreshView.pullView.hidden = NO;
[self.refreshView.loadingImageView.layer removeAllAnimations];
self.isLoading = NO;
}
并且在refreshControl的监听方法中调用
- (void)reloadData{
//在这里调用加载数据的方法
NSLog(@"刷新数据");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//结束刷新
[self.refreshControl endRefreshing];
});
}
默认是箭头向下,往下拉的时候箭头翻转到上面,在往下的时候下拉刷新的视图隐藏替换成正在加载的视图,刷新结束恢复到原来的状态.