iOS-Lottie和MJRefresh的配合使用
前言-OC-Lottie头部刷新
- 网易云音乐-QQ音乐-美团等使用的列表(滚动视图)的自定义MJRefresh头部刷新Lottie加载的json动画,再加上QQ音乐等刷新时的震感,现在已经比较多的在使用,做了一个例子
准备工作
- 导入pod ‘lottie-ios’, ‘=2.5.3’ 是OC版本
pod 'lottie-ios', '=2.5.3'
pod 'MJRefresh'
- Lottie动画例子下载
- 自己注册一个就可以下载了
- 直接点击lottie json就下载到本地了
- Lottie的一些使用方法在本文可能不够详细,可以进行其他的搜索
- 使用MVC的思想 xxx.json 在C中赋值给V
直接上代码 - 一共两个类 TestTableView 和 TestTableViewHeader
TestTableView
- TestTableView.h - 继承UIView
#import <UIKit/UIKit.h>
@interface TestTableView : UIView
@property(nonatomic, copy) void(^reloadHeadDataRefresh)(void);
- (void)endHeadAndFootRefresh;
- (void)setJsonName:(NSString *)string;
@end
#import "TestTableView.h"
#import "TestTableViewHeader.h"
#import <MJRefresh/MJRefresh.h>
static NSString *kCellID = @"cellID";
@interface TestTableView () <UITableViewDelegate, UITableViewDataSource>
@property(nonatomic, strong) UITableView *tableView;
@property(nonatomic, strong) TestTableViewHeader *testHeader;
@end
@implementation TestTableView
- (instancetype)initWithFrame:(CGRect)frame {
if(self = [super initWithFrame:frame]) {
[self addSubview:self.tableView];
}
return self;
}
- (void)endHeadAndFootRefresh {
[self.tableView.mj_header endRefreshing];
}
- (void)setJsonName:(NSString *)string {
[self.testHeader setJsonName:string];
self.tableView.mj_header = self.testHeader;
}
- (TestTableViewHeader *)testHeader {
if(_testHeader == nil) {
_testHeader = [[TestTableViewHeader alloc]init];
__weak typeof(self) weakSelf = self;
[self.testHeader setRefreshingBlock:^{
if(weakSelf.reloadHeadDataRefresh) {
weakSelf.reloadHeadDataRefresh();
}
[weakSelf.tableView.mj_header endRefreshing];
}];
}
return _testHeader;
}
#pragma mark - tableView
- (UITableView *)tableView {
if(_tableView == nil) {
_tableView = [[UITableView alloc]initWithFrame:self.bounds style:UITableViewStylePlain];
_tableView.backgroundColor = self.superview.backgroundColor;
_tableView.allowsSelection = NO;
_tableView.dataSource = self;
_tableView.delegate = self;
_tableView.rowHeight = 100;
}
return _tableView;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 100;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID];
if(cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellID];
}
cell.textLabel.text = [NSString stringWithFormat:@"%ld",(long)indexPath.row];
return cell;
}
@end
TestTableViewHeader
- TestTableViewHeader.h - 继承自MJRefreshGifHeader,不局限只要可以调用MJRefresh的一些方法即可
#import "MJRefreshGifHeader.h"
@interface TestTableViewHeader : MJRefreshGifHeader
- (void)setJsonName:(NSString *)jsonName;
@end
#import "TestTableViewHeader.h"
#import <AudioToolbox/AudioToolbox.h>
#import <Lottie/Lottie.h>
@interface TestTableViewHeader ()
@property(nonatomic, strong) LOTAnimationView *loadingView;
@property(nonatomic, strong) NSString *jsonString;
@end
@implementation TestTableViewHeader
- (instancetype)init {
if (self = [super init]) {
self.lastUpdatedTimeLabel.hidden = YES;
self.stateLabel.hidden = YES;
}
return self;
}
- (void)setJsonName:(NSString *)jsonName {
self.jsonString = jsonName;
[self addSubview:self.loadingView];
}
- (LOTAnimationView *)loadingView {
if(_loadingView == nil) {
_loadingView = [LOTAnimationView animationNamed:self.jsonString];
_loadingView.frame = CGRectMake(([UIScreen mainScreen].bounds.size.width / 2.0) - 25, 0, 50, 50);
_loadingView.loopAnimation = YES;
_loadingView.contentMode = UIViewContentModeScaleAspectFill;
_loadingView.animationSpeed = 1.0;
_loadingView.loopAnimation = YES;
}
return _loadingView;
}
#pragma mark - innerMethod
- (void)beginRefreshing {
if (@available(iOS 10.0, *)) {
UIImpactFeedbackGenerator *impactLight = [[UIImpactFeedbackGenerator alloc]initWithStyle:UIImpactFeedbackStyleMedium];
[impactLight impactOccurred];
} else {
AudioServicesPlaySystemSound(1520);
}
[super beginRefreshing];
}
- (void)endRefreshing {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[super endRefreshing];
});
}
#pragma mark - 监听控件的刷新状态
- (void)setState:(MJRefreshState)state {
MJRefreshCheckState;
if(self.jsonString.length > 0) {
switch (state) {
case MJRefreshStateIdle:{
[self.loadingView stop];
break;}
case MJRefreshStatePulling:{
break;}
case MJRefreshStateRefreshing:{
self.loadingView.animationProgress = 0;
[self.loadingView play];
break;}
default:
break;
}
}
}
#pragma mark - 实时监听控件 scrollViewContentOffset
- (void)scrollViewContentOffsetDidChange:(NSDictionary *)change {
[super scrollViewContentOffsetDidChange:change];
if(self.jsonString.length > 0) {
CGPoint point;
id newVelue = [change valueForKey:NSKeyValueChangeNewKey];
[(NSValue *)newVelue getValue:&point];
self.loadingView.hidden = !(self.pullingPercent);
CGFloat progress = point.y / ([UIScreen mainScreen].bounds.size.height / 3.0);
if(self.state != MJRefreshStateRefreshing) {
self.loadingView.animationProgress = -progress;
}
}
}
@end
例子的使用
- ViewController.m - 直接在新创建的工程的ViewController上使用
#import "ViewController.h"
#import "TestTableView.h"
@interface ViewController ()
@property(nonatomic, strong) TestTableView *testView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.testView];
[self.testView setJsonName:@"12345.json"];
}
- (TestTableView *)testView {
if(_testView == nil) {
_testView = [[TestTableView alloc]initWithFrame:self.view.bounds];
}
return _testView;
}
@end
Lottie 和 MJRefresh 使用的Demo下载