• iOS开发-Lottie实现下拉刷新动画效果


    iOS开发-Lottie实现下拉刷新动画效果

    在开发过程中,有时候需要自定义下拉刷新控件,这里使用Lottie实现下拉刷新动画效果。

    一、Lottie

    Lottie 是一个应用十分广泛动画库,适用于Android、iOS、Web、ReactNative、Windows的库,它解析了用Bodymovin导出为json的Adobe After Effects动画,并在移动和网络上进行了原生渲染。

    Lottie方法方案是由设计师出动画,导出为json,给前端、iOS、Android播放。

    在iOS开发中,我们需要使用lottie-ios库,在podfile中引入库

    pod ‘lottie-ios’, ‘~> 2.5.3’

    可以使用LOTAnimationView来进行动画播放。

    二、LOTAnimationView播放动画

    比如我们有一个loading_header,如图
    在这里插入图片描述

    使用LOTAnimationView来进行播放动画

    - (LOTAnimationView *)animationView {
        if (!_animationView) {
            _animationView = [[LOTAnimationView alloc] initWithFrame:CGRectZero];
            _animationView.backgroundColor = [UIColor clearColor];
            _animationView.frame = CGRectMake(0.0, 0.0, kAnimationSize, kAnimationSize);
            _animationView.loopAnimation = YES;
            [_animationView setAnimationNamed:@"loading_header"];
        }
        return _animationView;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    播放动画

    - (void)startAnimation {
        [self.animationView play];
    }
    
    
    • 1
    • 2
    • 3
    • 4

    停止动画播放

    - (void)stopAnimation {
        [self.animationView stop];
    }
    
    
    • 1
    • 2
    • 3
    • 4

    完整代码如下

    INRefreshGifLoadingView.h

    #import 
    
    @interface INRefreshGifLoadingView : UIView
    
    - (void)displayIndicator:(CGFloat)precent;
    
    - (void)startAnimation;
    
    - (void)stopAnimation;
    
    @end
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    INRefreshGifLoadingView.m

    #import "INRefreshGifLoadingView.h"
    #import 
    
    #import "UIColor+Addition.h"
    #import "UIImageView+WebCache.h"
    
    static CGFloat kAnimationSize = 60.0;
    
    @interface INRefreshGifLoadingView ()
    
    @property (nonatomic, strong) LOTAnimationView *animationView;
    
    @end
    
    @implementation INRefreshGifLoadingView
    
    - (instancetype)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            [self addSubview:self.animationView];
            [self layoutFrame];
        }
        return self;
    }
    
    - (void)layoutFrame {
        self.animationView.center = self.center;
    }
    
    #pragma mark - Display
    - (void)displayIndicator:(CGFloat)precent {
        
    }
    
    - (void)startAnimation {
        [self.animationView play];
    }
    
    - (void)stopAnimation {
        [self.animationView stop];
    }
    
    #pragma mark - SETTER/GETTER
    - (LOTAnimationView *)animationView {
        if (!_animationView) {
            _animationView = [[LOTAnimationView alloc] initWithFrame:CGRectZero];
            _animationView.backgroundColor = [UIColor clearColor];
            _animationView.frame = CGRectMake(0.0, 0.0, kAnimationSize, kAnimationSize);
            _animationView.loopAnimation = YES;
            [_animationView setAnimationNamed:@"loading_header"];
        }
        return _animationView;
    }
    
    @end
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    三、使用MJRefresh进行下拉刷新播放

    在使用MJRefresh时候,我们继承MJRefreshStateHeader来实现lottie动画播放效果。

    根据MJRefreshState来进行控制动画是否播放

    完整代码如下

    INRefreshHeader.h

    #import "MJRefresh.h"
    #import "INRefreshGifLoadingView.h"
    
    @interface INRefreshHeader : MJRefreshStateHeader
    
    @property (nonatomic, assign) BOOL showInsetTop;
    
    @property (nonatomic, strong) INRefreshGifLoadingView *gifLoadingView;
    
    @end
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    INRefreshHeader.m

    #import "INRefreshHeader.h"
    
    @implementation INRefreshHeader
    
    - (instancetype)initWithFrame:(CGRect)frame {
        if (self = [super initWithFrame:frame]) {
            self.lastUpdatedTimeLabel.hidden = YES;
            self.stateLabel.hidden = YES;
            [self addSubview:self.gifLoadingView];
        }
        return self;
    }
    
    - (INRefreshGifLoadingView *)gifLoadingView {
        if (!_gifLoadingView) {
            _gifLoadingView = [[INRefreshGifLoadingView alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth([UIScreen mainScreen].bounds), self.bounds.size.height)];
        }
        return _gifLoadingView;
    }
    
    - (void)setState:(MJRefreshState)state {
        MJRefreshCheckState
        
        // 根据状态做事情
        if (state == MJRefreshStateIdle) {
            if (oldState == MJRefreshStateRefreshing) {
                self.gifLoadingView.alpha = 1.0;
    
                // 如果执行完动画发现不是idle状态,就直接返回,进入其他状态
                if (self.state != MJRefreshStateIdle) return;
                
                
                self.gifLoadingView.alpha = 1.0;
    
                
                [self.gifLoadingView stopAnimation];
    
            } else {
                
                [self.gifLoadingView stopAnimation];
    
            }
        } else if (state == MJRefreshStatePulling) {
            
            [self.gifLoadingView stopAnimation];
    
        } else if (state == MJRefreshStateRefreshing) {
            
            [self.gifLoadingView startAnimation];
        }
    }
    
    - (void)prepare {
        [super prepare];
        self.mj_h = 70.0;
    }
    
    - (void)placeSubviews {
        [super placeSubviews];
        
        CGFloat centerX = self.mj_w * 0.5;
        CGFloat centerY = self.mj_h * 0.5;
        
        self.gifLoadingView.center = CGPointMake(centerX, centerY);
    }
    
    /** 当scrollView的contentOffset发生改变的时候调用 */
    - (void)scrollViewContentOffsetDidChange:(NSDictionary *)change {
        [super scrollViewContentOffsetDidChange:change];
        NSLog(@"change:%@",change);
        
        CGPoint old = [change[@"old"] CGPointValue];
        CGPoint new = [change[@"new"] CGPointValue];
        
        CGFloat precent = -new.y/self.mj_h;
        
        [self.gifLoadingView displayIndicator:precent];
    }
    
    /** 当scrollView的contentSize发生改变的时候调用 */
    - (void)scrollViewContentSizeDidChange:(NSDictionary *)change {
        [super scrollViewContentSizeDidChange:change];
    }
    
    /** 当scrollView的拖拽状态发生改变的时候调用 */
    - (void)scrollViewPanStateDidChange:(NSDictionary *)change {
        [super scrollViewPanStateDidChange:change];
    }
    
    - (void)setShowInsetTop:(BOOL)showInsetTop {
        _showInsetTop = showInsetTop;
        
    }
    
    - (void)backInitState {
        
    }
    
    @end
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100

    四、在TableView使用Refresh

    在设置UITableView 的mj_header,来进行使用下拉刷新动画效果。

    - (void)configureRefresh {
        __weak typeof(self) weakSelf = self;
        INRefreshHeader *header = [INRefreshHeader headerWithRefreshingBlock:^{
            [weakSelf refreshData];
        }];
        
        self.noteView.tableView.mj_header = header;
    }
    
    - (void)refreshData {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self.noteView.tableView.mj_header endRefreshing];
        });
    }
    
    - (void)loadMoreData {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [self.noteView.tableView.mj_header endRefreshing];
        });
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    Lottie实现下拉刷新动画效果如下

    在这里插入图片描述

    五、小结

    iOS开发-Lottie实现下拉刷新动画效果

    学习记录,每天不停进步。

  • 相关阅读:
    【常见错误】npm ERR! code CERT_HAS_EXPIRED & errno CERT_HAS_EXPIRED
    java基于ssm的高校人事员工工资管理系统
    前端经典面试题 | Computed 和 Watch 的区别
    溅射生长的铜和钨薄膜的应力调整
    分组交换技术
    vue+vite项目静态文件引用丢失
    为什么你的项目总延期?多半是没做好5件事
    爱思唯尔——利用AI来改善医疗决策和科研
    Python colorama 设置控制台、命令行输出彩色文字
    Codeforces Round #787 (Div. 3) F. Vlad and Unfinished Business
  • 原文地址:https://blog.csdn.net/gloryFlow/article/details/134060000