ios使用CAShapeLayer,UIBezierPath,CABasicAnimation 画百分比圆圈

1. 普通的用法(先学习咋用)

代码如下

- (void)viewDidLoad {
    [super viewDidLoad];
    
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.frame = CGRectMake(50, 50, 150, 150);
    shapeLayer.strokeEnd = 1.0f;
    shapeLayer.strokeStart = 0.0f;
    shapeLayer.lineWidth     = 10;          //设置线宽
    shapeLayer.lineCap       = kCALineCapRound;    //设置线头形状
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:shapeLayer.frame];
    shapeLayer.path = path.CGPath;
    shapeLayer.fillColor = [UIColor clearColor].CGColor;
    shapeLayer.strokeColor = [UIColor redColor].CGColor;
    shapeLayer.fillRule       = kCAFillRuleEvenOdd;  //重点, 填充规则
    
    CABasicAnimation *pathAnima = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    pathAnima.duration = 10.0f;				//动画时间
    pathAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];      //动画的运动曲线
    pathAnima.fromValue = [NSNumber numberWithFloat:0.0f];		//值 开始
    pathAnima.toValue = [NSNumber numberWithFloat:1.0f];			//值 结束
    pathAnima.fillMode = kCAFillModeBoth;									//填充方式,反正我是没试通。。。求大佬解释
    pathAnima.removedOnCompletion = NO;									//完成后是否删除动画
    [shapeLayer addAnimation:pathAnima forKey:@"strokeEndAnimation"];//不知道,求大佬解释
    [self.view.layer addSublayer:shapeLayer];
}

效果如下:

在这里插入图片描述

【那怎么做从12点开始方向开始的动画】

  • CABasicAnimation 给CAShapeLayer的strokeStart和strokeEnd属性进行控制来进行动画
  • 但是这个方法没法让圆的开始在12点的方向,因为。。。官方说
    在这里插入图片描述

2. 更好的用法

CAShapeLayer的path定为从12点开始的圆就行了。

这个好像就是用来画线条的函数:
[UIBezierPath bezierPathWithArcCenter:self.view.center radius:(mybound.size.width - 0.7)/ 2 startAngle:0 endAngle:M_PI * 2 clockwise:YES];
顺时针情况:
radius: 半径
startAngle :-180
endAngle:180
clockwise:YES 顺时针
逆时针情况:
startAngle :180
endAngle:-180

- (void)viewDidLoad {
    [super viewDidLoad];
    CGRect mybound = CGRectMake(50, 200, 150, 150);
    [self startProgressAction:mybound];
}

//画两个圆形
-(void)startProgressAction:(CGRect)mybound
{
    static CGFloat hudu = 1;
    //底下的框(灰色)不会动的
    _trackPath = [UIBezierPath bezierPathWithArcCenter:self.view.center radius:(mybound.size.width - 0.7)/ 2 startAngle:0 endAngle:M_PI * 2 clockwise:YES];
    
    _trackLayer = [CAShapeLayer new];
    [self.view.layer addSublayer:_trackLayer];
    _trackLayer.fillColor = nil;
    _trackLayer.strokeColor=[UIColor grayColor].CGColor;
    _trackLayer.path = _trackPath.CGPath;
    _trackLayer.lineWidth=10;
    _trackLayer.frame = mybound;
    
    //会动的
    _progressPath = [UIBezierPath bezierPathWithArcCenter:self.view.center radius:(mybound.size.width - 0.7)/ 2 startAngle:- M_PI_2 endAngle:(M_PI * 2) - M_PI_2 clockwise:YES];
    
    _progressLayer = [CAShapeLayer new];
    [self.view.layer addSublayer:_progressLayer];
    _progressLayer.fillColor = nil;
    _progressLayer.strokeColor=[UIColor redColor].CGColor;
    _progressLayer.lineCap = kCALineCapRound;
    _progressLayer.path = _progressPath.CGPath;
    _progressLayer.lineWidth=10;
    _progressLayer.frame = mybound;
    _progressLayer.strokeEnd = 1;
    _progressLayer.strokeStart = 0;
    
    CABasicAnimation *pathAnima2 = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    pathAnima2.duration = 10.0f;
    pathAnima2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    pathAnima2.fromValue = [NSNumber numberWithFloat:0.0f];
    pathAnima2.toValue = [NSNumber numberWithFloat:1.0f];
    pathAnima2.fillMode = kCAFillModeBoth;
    pathAnima2.removedOnCompletion = NO;
    [_progressLayer addAnimation:pathAnima2 forKey:@"strokeEndAnimation"];
}

效果就自己试,反正就是赋值粘贴的事~

后记:

使用

// 圆的动画
-(void)startBTProgressAction:(CGFloat)timeRange nowTime:(CGFloat)nowTime
{
    CGFloat startPos = nowTime/timeRange;
    CGFloat duration = timeRange - nowTime;
    
    CABasicAnimation *pathAnima2 = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    pathAnima2.duration = duration;
    pathAnima2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    pathAnima2.fromValue = [NSNumber numberWithFloat:startPos];
    pathAnima2.toValue = [NSNumber numberWithFloat:1.0f];
    pathAnima2.fillMode = kCAFillModeForwards;
    pathAnima2.removedOnCompletion = NO;           //YES:app在后台时移除动画
    if (timeRange <= 0) {
        //self.progressShapeLayer.strokeColor = HexRGB(0xFAF6F2).CGColor;
    }else{
        self.progressShapeLayer.strokeColor = HexRGB(0xE0B482).CGColor;
    }
    [self.progressShapeLayer addAnimation:pathAnima2 forKey:@"strokeEndAnimation"];
}
//显示逻辑
- (void)showView{
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    [window addSubview:self];
    
    [self mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(window);
    }];
    [CTCGCDQueue executeInMainQueue:^{
        [UIView animateWithDuration:0.23 animations:^{
            //self.transform = CGAffineTransformIdentity;
            self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
        }completion:^(BOOL finished) {
        }];
    }afterDelaySecs:0.1];

//开始计时
- (void)createStatusTimer
{
    dispatch_async(dispatch_get_main_queue(), ^{
        if (!_timer)
        {
            _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timing) userInfo:nil repeats:NO];
        }
        [_timer fire];
    });
}
//超时处理函数
- (void)timing
{
    if (_timeCount > self.totolTime)
    {   // 超时
        [self dismiss];
    }
    NSLog(@"timecount:%ld",(long)_timeCount);
    ++_timeCount;
}

// 关闭计时器
- (void)revokeTimer
{
    if (_timer)
    {
        [_timer invalidate];
        _timeCount = 0;
        _timer = nil;
    }
}

-(void)dismiss {
    [self revokeTimer];
    [self removeFromSuperview];
}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路途遥远gg

帮到你了就好

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值