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.jsonC中赋值给V

直接上代码 - 一共两个类 TestTableView 和 TestTableViewHeader

TestTableView

  • TestTableView.h - 继承UIView
#import <UIKit/UIKit.h>

@interface TestTableView : UIView

@property(nonatomic, copy) void(^reloadHeadDataRefresh)(void);//刷新回调block
- (void)endHeadAndFootRefresh;//结束刷新block

- (void)setJsonName:(NSString *)string;

@end
  • TestTableView.m
#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
  • TestTableViewHeader.m
#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) {
        //1.加载本地json
        _loadingView = [LOTAnimationView animationNamed:self.jsonString];
        //2.加载后台给的json(url)
        //_loadingView = [[LOTAnimationView alloc] initWithContentsOfURL:[NSURL URLWithString:urlString]];
        _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];
                //self.loadingView.hidden = YES;
                break;}
            case MJRefreshStatePulling:{//松开就可以进行刷新的状态
                //self.loadingView.hidden = NO;
                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];
        
        //id newVelue1 = [change objectForKey:NSKeyValueChangeNewKey];
        //CGPoint point1 = ((NSValue *)newVelue1).CGPointValue;//可以取值
        
        //id newVelue2 = [change objectForKey:@"new"];
        //CGPoint point2 = *((__bridge CGPoint *)(newVelue2));//无法取到值
        
        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下载

发布了31 篇原创文章 · 获赞 0 · 访问量 939

猜你喜欢

转载自blog.csdn.net/weixin_41732253/article/details/104048437