前言:
项目中UI没有给我们设计下拉刷新动画,本人用的MJRefresh默认的加载动画。
因为我们的产品属于商城类应用,加上自己最近这几天有点空余时间,就模仿了一下JD的下拉刷新动画。
跟京东首页的刷新不同之处:
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的动画则是在这三种状态下都是启动状态,想了想,还是没有想到好的解决思路。