zoukankan      html  css  js  c++  java
  • 等待时动画效果的实现

    当我们在请求网络时加载页面时有个动作效果,效果如下:

    源代码可以网上找开源项目Coding.net,上面的效果原理为两张图片组合,外面那个则为动画转动,里面的图标则是透明度的变化;主要代码如下:

    1:把它封装在EaseLoadingView里面

    @interface EaseLoadingView : UIView
    @property (strong, nonatomic) UIImageView *loopView, *monkeyView;
    @property (assign, nonatomic, readonly) BOOL isLoading;
    - (void)startAnimating;
    - (void)stopAnimating;
    @end
    @interface EaseLoadingView ()
    @property (nonatomic, assign) CGFloat loopAngle, monkeyAlpha, angleStep, alphaStep;
    @end
    
    
    @implementation EaseLoadingView
    
    - (instancetype)initWithFrame:(CGRect)frame{
        self = [super initWithFrame:frame];
        if (self) {
            self.backgroundColor = [UIColor clearColor];
            _loopView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"loading_loop"]];
            _monkeyView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"loading_monkey"]];
            [_loopView setCenter:self.center];
            [_monkeyView setCenter:self.center];
            [self addSubview:_loopView];
            [self addSubview:_monkeyView];
            [_loopView mas_makeConstraints:^(MASConstraintMaker *make) {
                make.center.equalTo(self);
            }];
            [_monkeyView mas_makeConstraints:^(MASConstraintMaker *make) {
                make.center.equalTo(self);
            }];
            
            _loopAngle = 0.0;
            _monkeyAlpha = 1.0;
            _angleStep = 360/3;
            _alphaStep = 1.0/3.0;
        }
        return self;
    }
    
    - (void)startAnimating{
        self.hidden = NO;
        if (_isLoading) {
            return;
        }
        _isLoading = YES;
        [self loadingAnimation];
    }
    
    - (void)stopAnimating{
        self.hidden = YES;
        _isLoading = NO;
    }
    
    - (void)loadingAnimation{
        static CGFloat duration = 0.25f;
        _loopAngle += _angleStep;
        if (_monkeyAlpha >= 1.0 || _monkeyAlpha <= 0.0) {
            _alphaStep = -_alphaStep;
        }
        _monkeyAlpha += _alphaStep;
        [UIView animateWithDuration:duration delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^{
            CGAffineTransform loopAngleTransform = CGAffineTransformMakeRotation(_loopAngle * (M_PI / 180.0f));
            _loopView.transform = loopAngleTransform;
            _monkeyView.alpha = _monkeyAlpha;
        } completion:^(BOOL finished) {
            if (_isLoading && [self superview] != nil) {
                [self loadingAnimation];
            }else{
                [self removeFromSuperview];
    
                _loopAngle = 0.0;
                _monkeyAlpha = 1,0;
                _alphaStep = ABS(_alphaStep);
                CGAffineTransform loopAngleTransform = CGAffineTransformMakeRotation(_loopAngle * (M_PI / 180.0f));
                _loopView.transform = loopAngleTransform;
                _monkeyView.alpha = _monkeyAlpha;
            }
        }];
    }
    
    @end

    注意loadingAnimation这里面有动作的处理及透明度的处理,当停止加载后把它自个从当前的视图去除;

    2:UIView (Common)在UIView扩展类里

    #pragma mark LoadingView
    @property (strong, nonatomic) EaseLoadingView *loadingView;
    - (void)beginLoading;
    - (void)endLoading;
    @end
    - (void)setLoadingView:(EaseLoadingView *)loadingView{
        [self willChangeValueForKey:@"LoadingViewKey"];
        objc_setAssociatedObject(self, &LoadingViewKey,
                                 loadingView,
                                 OBJC_ASSOCIATION_RETAIN_NONATOMIC);
        [self didChangeValueForKey:@"LoadingViewKey"];
    }
    - (EaseLoadingView *)loadingView{
        return objc_getAssociatedObject(self, &LoadingViewKey);
    }
    
    - (void)beginLoading{
        for (UIView *aView in [self.blankPageContainer subviews]) {
            if ([aView isKindOfClass:[EaseBlankPageView class]] && !aView.hidden) {
                return;
            }
        }
        
        if (!self.loadingView) { //初始化LoadingView
            self.loadingView = [[EaseLoadingView alloc] initWithFrame:self.bounds];
        }
        [self addSubview:self.loadingView];
        [self.loadingView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.self.edges.equalTo(self);
        }];
        [self.loadingView startAnimating];
    }
    
    - (void)endLoading{
        if (self.loadingView) {
            [self.loadingView stopAnimating];
        }
    }

    注意:cocoa的KVO模型中,有两种通知观察者的方式,自动通知和手动通知。顾名思义,自动通知由cocoa在属性值变化时自动通知观察者,而手动通知需要在值变化时调用 willChangeValueForKey:和didChangeValueForKey: 方法通知调用者。

    3:使用页面调用

    - (void)sendRequest{
        [self.view beginLoading];
        __weak typeof(self) weakSelf = self;
        [[Coding_NetAPIManager sharedManager] request_CodeFile:_myCodeFile withPro:_myProject andBlock:^(id data, NSError *error) {
            [weakSelf.view endLoading];
            if (data) {
                weakSelf.myCodeFile = data;
                [weakSelf refreshCodeViewData];
            }
            [weakSelf.view configBlankPage:EaseBlankPageTypeView hasData:(data != nil) hasError:(error != nil) reloadButtonBlock:^(id sender) {
                [weakSelf sendRequest];
            }];
        }];
    }

    其中[self.view beginLoading]跟[weakSelf.view endLoading]就可以调用动画效果;

    补充:另一种是有很多不同的图片组成的动画效果,可以用每一张图片然后FOR遍历组成出动作效果;

        //设置普通状态的动画图片
        NSMutableArray *idleImages = [NSMutableArray array];
        for (NSUInteger i = 1; i<=60; ++i) {
                   UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"dropdown_anim__000%zd",i]];
                   [idleImages addObject:image];
            [idleImages addObject:image];
        }
  • 相关阅读:
    循环事件绑定和原型的应用
    小知识随手记(四)
    JavaScript数组与字符串常用方法总结
    jquery获得select option的值和对select option的操作
    前端图片上传前预览
    CSS 的优先级机制总结
    汇编语言学习笔记(8)——数据处理的基本问题
    SPOJ 1811LCS Longest Common Substring
    mysql 安装完毕后登陆不了mysql的 shell 即mysql&gt;遇到:ERROR 1045 (28000): Access denied for user 'root'@'localhost‘
    [LeetCode]Power of Two
  • 原文地址:https://www.cnblogs.com/wujy/p/4714053.html
Copyright © 2011-2022 走看看