模拟下载进度动画 (动画监听)

//监听事件

-(void)setUpSomething{

UITapGestureRecognizer *tapGes = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapped:)];
    [self addGestureRecognizer:tapGes];

}

//点击动画

#pragma mark -- UITapGesture
-(void)tapped:(UITapGestureRecognizer *)tapped{
    originframe = self.frame;
   
    if (animating == YES) {
        return;
    }
   
    for (CALayer *subLayer in self.layer.sublayers) {
        [subLayer removeFromSuperlayer];
    }

self.backgroundColor = [UIColor colorWithRed:0.0 green:122/255.0 blue:255/255.0 alpha:1.0];

animating = YES;

self.layer.cornerRadius = self.progressBarHeight/2;
   
    //注意:[UIView animate]的方法里只能对UIView的属性进行动画,对于layer的属性是无效的。比如你在这里想让self.AnimateView.layer.cornerRadius = 50.0; 是没有意义的。必须使用CoreAnimation。
    CABasicAnimation *radiusAnimation = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
    radiusAnimation.duration = 0.2f;
    radiusAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    radiusAnimation.fromValue = @(originframe.size.height/2);
   
    //不需要设置toValue了
    radiusAnimation.delegate = self;
    [self.layer addAnimation:radiusAnimation forKey:@"cornerRadiusShrinkAnim"];

}

-(void)animationDidStart:(CAAnimation *)anim{
   
    //这里介绍两种方式区分不同的anim 1、对于加在一个全局变量上的anima,比如例子里的self.AnimateView ,这是一个全局变量,所以我们在这里可以通过[self.AnimateView.layer animationForKey:]根据动画不同的key来区分
    //2、然而对于一个非全局的变量,比如demo中的progressLayer,可以用KVO:[pathAnimation setValue:@"strokeEndAnimation" forKey:@"animationName"];注意这个animationName是我们自己设定的。
   
    if ([anim isEqual:[self.layer animationForKey:@"cornerRadiusShrinkAnim"]]) {
       
        [UIView animateWithDuration:0.6f delay:0.0f usingSpringWithDamping:0.6 initialSpringVelocity:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
            self.bounds = CGRectMake(0, 0, _progressBarWidth, _progressBarHeight);
        } completion:^(BOOL finished) {
            [self.layer removeAllAnimations];
            [self progressBarAnimation];
        }];
       
    }else if ([anim isEqual:[self.layer animationForKey:@"cornerRadiusExpandAnim"]]){
       
        [UIView animateWithDuration:0.6f delay:0.0f usingSpringWithDamping:0.6 initialSpringVelocity:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
            self.bounds = CGRectMake(0, 0, originframe.size.width, originframe.size.height);
            self.backgroundColor = [UIColor colorWithRed:0.1803921568627451 green:0.8 blue:0.44313725490196076 alpha:1.0];
        } completion:^(BOOL finished) {
            [self.layer removeAllAnimations];
            [self checkAnimation];
            //-----
            animating = NO;
        }];
       
    }
}

-(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
   
    if ([[anim valueForKey:@"animationName"]isEqualToString:@"progressBarAnimation"]){
       
        [UIView animateWithDuration:0.3 animations:^{
            for (CALayer *subLayer in self.layer.sublayers) {
                subLayer.opacity = 0.0f;
            }
        } completion:^(BOOL finished) {
            if (finished) {
                for (CALayer *subLayer in self.layer.sublayers) {
                    [subLayer removeFromSuperlayer];
                }
               
                self.layer.cornerRadius = originframe.size.height/2;
               
                CABasicAnimation *radiusAnimation = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];
                radiusAnimation.duration = 0.2f;
                radiusAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
                radiusAnimation.fromValue = @(_progressBarHeight/2);
               
                radiusAnimation.delegate = self;
                [self.layer addAnimation:radiusAnimation forKey:@"cornerRadiusExpandAnim"];
               
            }
        }];

}

}

//开始进度动画
-(void)progressBarAnimation{
   
    CAShapeLayer *progressLayer = [CAShapeLayer layer];
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(_progressBarHeight/2, self.bounds.size.height/2)];
    [path addLineToPoint:CGPointMake(self.bounds.size.width-_progressBarHeight/2, self.bounds.size.height/2)];
   
    progressLayer.path = path.CGPath;
    progressLayer.strokeColor = [UIColor greenColor].CGColor;
    progressLayer.lineWidth = _progressBarHeight-4;
    progressLayer.lineCap = kCALineCapRound;
    //设置了kCALineCapRound 那么圆角弧度自动被设为 lineWidth/2 .所以要想进度条距离外围的间距相等,起始点的 x 坐标应该等于满足公式 x=lineWidth/2+space; ∵ lineWidth = _progressBarHeight-space*2 ∴x = height/2.与 linewidth 是多少并没有关系
    [self.layer addSublayer:progressLayer];
   
    CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    pathAnimation.duration = 1.0f;
    pathAnimation.fromValue = @(0.0f);
    pathAnimation.toValue = @(1.0f);
    pathAnimation.delegate = self;
    [pathAnimation setValue:@"progressBarAnimation" forKey:@"animationName"];
    [progressLayer addAnimation:pathAnimation forKey:nil];
   
}

//完成后钩钩动画
-(void)checkAnimation{
   
    CAShapeLayer *checkLayer = [CAShapeLayer layer];
   
   
    UIBezierPath *path = [UIBezierPath bezierPath];
    CGRect rectInCircle = CGRectInset(self.bounds, self.bounds.size.width*(1-1/sqrt(2.0))/2, self.bounds.size.width*(1-1/sqrt(2.0))/2);
    [path moveToPoint:CGPointMake(rectInCircle.origin.x + rectInCircle.size.width/9, rectInCircle.origin.y + rectInCircle.size.height*2/3)];
    [path addLineToPoint:CGPointMake(rectInCircle.origin.x + rectInCircle.size.width/3,rectInCircle.origin.y + rectInCircle.size.height*9/10)];
    [path addLineToPoint:CGPointMake(rectInCircle.origin.x + rectInCircle.size.width*8/10, rectInCircle.origin.y + rectInCircle.size.height*2/10)];
   
    checkLayer.path = path.CGPath;
    checkLayer.fillColor = [UIColor clearColor].CGColor;
    checkLayer.strokeColor = [UIColor whiteColor].CGColor;
    checkLayer.lineWidth = 5.0;
    checkLayer.lineCap = kCALineCapRound;
    checkLayer.lineJoin = kCALineJoinRound;
    [self.layer addSublayer:checkLayer];
   
   
    //增加画画的时间
    CABasicAnimation *checkAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    checkAnimation.duration = 0.3f;
    checkAnimation.fromValue = @(0.0f);
    checkAnimation.toValue = @(1.0f);
    checkAnimation.delegate = self;
    [checkAnimation setValue:@"checkAnimation" forKey:@"animationName"];
    [checkLayer addAnimation:checkAnimation forKey:nil];

}

时间: 2024-11-02 10:56:25

模拟下载进度动画 (动画监听)的相关文章

Android属性动画的监听事件

整体很简单,直接上代码吧.activity_main.xml: 1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:tools="http://schemas.android.com/tools" 4 andro

iOS Quartz2D模拟下载进度条

效果图: 步骤: 1.在StoryBoard中拖入一个控制器添加UISlider和UIView 2个控件 2.在控制器中连线监听UISlider的值变化事件.HJProgressView属性,把变化的值传递给自定义UIView 3.自定义HJProgressView重写progressValue属性set方法,重绘视图中得文字和弧度值 控制器代码: #import "ViewController.h" #import "HJProgressView.h" @inte

24模拟keepalved vrrp功能,监听主节点,如果主节点不可访问则备节点启动并配置LVS实现接管主节点的资源提供服务(提醒:注意ARP缓存)

[[email protected] scripts]# cat ha_lv.sh #!/bin/bash while true do check_count=$(nmap 10.0.0.13|grep "Host is up"|wc -l) if [ ${check_count} -ne 1 ] then sh /server/scripts/lv_manager.sh start echo "切换服务器到16从服务器" arping -I eth0 -c 1 -

模拟下载进度条

import time def process(percent, width=30): percent = percent if percent <= 1 else 1 text=('\r[%%-%ds]'%width)%('*'*int(width*percent)) text=text+'%d%%' text=text%(percent*100) print(text,end='') file_size=10240 cur_size=0 while True: time.sleep(0.01

关于v4包的Fragment过渡动画的事件监听无响应问题解决

项目中部分功能模块采用了单Activity+多Fragment模式,当Fragment切换时,需要在过渡动画执行完后做一些操作,通常就是在自己封装的FragmentBase中重写onCreateAnimation方法,创建一个Animation对象,并添加动画的事件监听.而最近升级了v4包后,突然发现添加的动画事件监听无响应了.通过查看源码,发现在v4包中关于Fragment管理类FragmentManagerImpl中,在获取Animation对象后,也添加了对动画的监听事件,也就覆盖了我自己

不浮夸且不单调——监听鼠标图片移动动画

鼠标监听实现图片动画 这是一个小的动画,监听鼠标的移动,来实现 图片的移动视觉特效.虽然功能不是那么的强大,但应用范围还是很广泛的,不浮夸且不是单调. 先给大家欣赏一下样式. 小样子 代码: <!doctype html> <html> <head> <meta charset="utf-8"> <title>鼠标移动图片</title> <style> body { margin: 0; backgr

各类监听时间整理

键盘监听事件 local function onKeyReleased(keyCode, event) local label = event:getCurrentTarget() if keyCode == cc.KeyCode.KEY_BACK then label:setString("BACK clicked!") elseif keyCode == cc.KeyCode.KEY_MENU then label:setString("MENU clicked!&quo

Android群英传笔记系列三 view的自定义:实现一个模拟下载

1.实现效果:动态显示进度(分别显示了整个的动态改变的过程,然后完成后,弹出一个对话框)       2.实现过程:可以分为绘制一个圆,圆弧和文本三部分,然后在MainAcitivity中通过线程模拟下载进度. a.定义一个类继承至view,然后添加其构造函数,记得一定要添加含有Attributset参数的构造函数; b.定义和初始化一些数据: private int mCircleXY; private int mWidth; private float mRadius; private Pa

Android通过Intent.ACTION_CLOSE_SYSTEM_DIALOGS监听Home按键消息

Android对屏幕下方经常使用的四个按键消息处理是不一致的: 1.搜索按键的消息在onKeyDown或者onKeyUp中接收: 2.菜单按键的消息在onCreateOptionsMenu.onKeyDown或onKeyUp方法中接收: 3.返回按键的消息能够在onBackPressed.onKeyDown或onKeyUp方法中接收. @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch( keyCode