iOS:自定义下拉刷新视图和下拉刷新原理

首先自定义一个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];
    });
}

默认是箭头向下,往下拉的时候箭头翻转到上面,在往下的时候下拉刷新的视图隐藏替换成正在加载的视图,刷新结束恢复到原来的状态.
最终效果

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值