iOS 仿京东下拉刷新动画

iOS 仿京东下拉刷新动画_第1张图片
7.jpg
前言:

项目中UI没有给我们设计下拉刷新动画,本人用的MJRefresh默认的加载动画。
因为我们的产品属于商城类应用,加上自己最近这几天有点空余时间,就模仿了一下JD的下拉刷新动画。


iOS 仿京东下拉刷新动画_第2张图片
HeaderRefresh.gif

跟京东首页的刷新不同之处:
1、图片,没有找到JD最新的资源包,@.@
2、快递员不是一直在奔跑的(如果哪位仁兄,有好的想法,可以讨论一下)

实现

这里,我是基于MJRefresh库写的,定义一个类YJRefreshGifHeader,继承于MJRefreshGifHeader类

#import "MJRefreshGifHeader.h"

@interface YJRefreshGifHeader : MJRefreshGifHeader
/** 显示描述文本*/
@property (weak, nonatomic, readonly) UILabel *msgLabel;

/** 设置描述文本*/
- (void)setMessage:(NSString *)message;

@end
#import "YJRefreshGifHeader.h"
@interface YJRefreshGifHeader()
{
    __unsafe_unretained UILabel *_msgLabel;
}

@end

@implementation YJRefreshGifHeader
#pragma mark - 懒加载
- (UILabel *)msgLabel {
    if (!_msgLabel) {
        UILabel *label = [[UILabel alloc] init];
        label.font = [UIFont systemFontOfSize:15];
        label.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        label.textAlignment = NSTextAlignmentLeft;
        label.backgroundColor = [UIColor clearColor];
        _msgLabel = label;
        [self addSubview:_msgLabel];
    }
    return _msgLabel;
}

#pragma mark - 公共方法
- (void)setMessage:(NSString *)message {
    self.msgLabel.text = message;
}

#pragma mark - 重写父类方法
- (void)prepare {
    [super prepare];
    self.lastUpdatedTimeLabel.hidden = YES;
    self.stateLabel.font = [UIFont systemFontOfSize:12];
}

- (void)placeSubviews {
    [super placeSubviews];
    [self.gifView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self).offset(-50);
        make.bottom.equalTo(self).offset(self.mj_h/2.f);
    }];
    //设置锚点
    self.gifView.layer.anchorPoint = CGPointMake(0.5, 1.0);
    [self.msgLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.equalTo(self).offset(50);
        make.top.equalTo(self).offset(10);
    }];
    [self.stateLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.msgLabel);
        make.top.equalTo(self.msgLabel.mas_bottom).offset(10);
    }];
}

- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change {
    [super scrollViewContentOffsetDidChange:change];
    if (self.scrollView.isDragging) {
        CGFloat offsetY = -self.scrollView.contentOffset.y;
        CGFloat validY = self.scrollViewOriginalInset.top;
        CGFloat offsetH = offsetY - validY;
        CGFloat scale = offsetH < self.mj_h ? offsetH / self.mj_h : 1;
        [self.gifView setTransform:CGAffineTransformMakeScale(scale, scale)];
    }
}

@end

调用

#import "HomeViewController.h"
#import "YJRefreshGifHeader.h"
@interface HomeViewController ()
@end

@implementation HomeViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    YJRefreshGifHeader *header = [YJRefreshGifHeader headerWithRefreshingBlock:^{
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self.tableView.mj_header endRefreshing];
        });
    }];
    NSMutableArray *arrayM = [NSMutableArray array];
    for (int i=1; i<3; i++) {
        [arrayM addObject:[UIImage imageNamed:[NSString stringWithFormat:@"deliveryStaff%d",i]]];
    }
    [header setImages:arrayM forState:MJRefreshStateRefreshing];
    [header setImages:arrayM forState:MJRefreshStateIdle];
    [header setImages:arrayM forState:MJRefreshStatePulling];
    [header setMessage:@"让购物更健康"];
    [header setTitle:@"更新中..." forState:MJRefreshStateRefreshing];
    [header setTitle:@"下拉更新..." forState:MJRefreshStateIdle];
    [header setTitle:@"松手更新..." forState:MJRefreshStatePulling];
    self.tableView.mj_header = header;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

@end

由于封装是集成于MJRefreshGifHeader,受限制比较大,

- (void)setState:(MJRefreshState)state
{
    MJRefreshCheckState
    
    // 根据状态做事情
    if (state == MJRefreshStatePulling || state == MJRefreshStateRefreshing) {
        NSArray *images = self.stateImages[@(state)];
        if (images.count == 0) return;
        
        [self.gifView stopAnimating];
        if (images.count == 1) { // 单张图片
            self.gifView.image = [images lastObject];
        } else { // 多张图片
            self.gifView.animationImages = images;
            self.gifView.animationDuration = [self.stateDurations[@(state)] doubleValue];
            [self.gifView startAnimating];
        }
    } else if (state == MJRefreshStateIdle) {
        [self.gifView stopAnimating];
    }
}

可以看到,在MJRefreshStateIdle状态下,动画是停止的,只有在MJRefreshStatePulling和MJRefreshStateRefreshing这两种状态下,动画才是启动的。对比JD的动画则是在这三种状态下都是启动状态,想了想,还是没有想到好的解决思路。

你可能感兴趣的:(iOS 仿京东下拉刷新动画)