IOS之核心动画画圆

作者: 辛小二 | 来源:发表于2017-08-01 10:25 被阅读1935次
个人Logo
目录
一、首先我们需要画一个圆
实现方法、下面通过三种方式进行绘制圆   分别为1、贝塞尔曲线绘制 2、CGPathRef绘制 3、CGContextRef绘制
二、利用系统UISlider的滑动事件和核心动画CABasicAnimation对圆弧度的变化做到实时监听
实现方法:(1)实现UISlider的滑动事件(2)创建类继承CALayer来实现核心动画(3)在视图中通过传递属性的方式,实时更改绘制圆的角度,从而实现UISlider对圆弧度的监听
三、将随时更改弧度的变化值赋值到label上,实现百分比效果。
效果图
一、绘制一个圆
//方法1
    /*通过贝塞尔曲线 UIBezierPath 来绘制圆*/
//    UIBezierPath * path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(100, 100, 200, 200)];
//    [[UIColor colorWithRed:0.5 green:0.5 blue:0.9 alpha:1.0] setStroke];/*设置线的颜色*/
//    /*线的粗度*/
//    [path setLineWidth:10.0];
//    /*绘画的最后一步,它之于绘图的意义如画画的最后上颜料一样。
//     
//       渲染分为两种方式:
//       1)填充Fill:将路径内部填充渲染
//       2)描边Stroke:不填充,只对路径进行渲染*/
//    [path stroke];
//方法2
//    /*通过CGPathRef 来绘制圆*/
//    //获取上下文
//    CGContextRef ctx = UIGraphicsGetCurrentContext();
//    //创建可变路径
//    CGMutablePathRef path = CGPathCreateMutable();
//    //添加圆形到路径中(所在路径、不进行变换操作、中心坐标200、200、起点弧度0、终点弧度2PI、画的方向0逆1正)
//    CGPathAddArc(path, NULL, 200, 200, 100, 0, M_PI * 2, 1);
//    //将路径添加到上下文
//    CGContextAddPath(ctx, path);
//    //修改图形状态参数
//    CGContextSetRGBStrokeColor(ctx, 0.5, 0.5, 0.9, 1.0);//笔颜色
//    CGContextSetLineWidth(ctx, 10);//线条宽度
//    //渲染上下文
//    CGContextStrokePath(ctx);
//方法3
    //使用CGContextRef创建路径
//    //获取上下文
//    CGContextRef ctx = UIGraphicsGetCurrentContext();
//    //绘制路径: 圆形(中心坐标200、200、半径100、起点弧度0、终点弧度2PI、画的方向0逆1正) 第五个参数 是startAngle开始的角度
//    CGContextAddArc(ctx, 200, 200, 100, 0, M_PI *2, 1);
//    /*给当前View一个边框*/
////    CGContextAddRect(ctx, self.bounds);
//    //修改图形状态参数
//    CGContextSetRGBStrokeColor(ctx, 0.5, 0.5, 0.9, 2.0);//笔颜色
//    CGContextSetLineWidth(ctx, 10);//线条宽度
//    //渲染上下文
//    CGContextStrokePath(ctx);
二、利用系统UISlider的滑动事件和核心动画CABasicAnimation对圆弧度的变化做到实时监听

整体流程:
开始
---->UISlider 通过滑动的方式更改本身value的属性
----->更改drawview视图中创建progress的属性
----->再通过核心动画的生命周期animationDidStop的方法将drawview视图中progress属性传递给继承CALayer类CircleProgressLayer中progress的属性
----->再通过重载其绘图方法 drawInContext,并在progress属性变化时让其重绘,不断的更改贝塞尔曲线绘制圆中endAngle的值,从而达到不同弧度的效果
结束

1)创建UISlider,并声明UISlider的滑动事件

UISlider * slider = [[UISlider alloc]initWithFrame:CGRectMake(50, 400, 275, 10)];
    [slider addTarget:self action:@selector(changeProgress:) forControlEvents:UIControlEventValueChanged];
    slider.maximumValue = 1.0;
    slider.minimumValue = 0.f;
    slider.value = self.drawview.progress;
    [self.view addSubview:slider];

2)实现UISlider的滑动事件,并把UISlider的value传递给视图的progress属性

- (void)changeProgress:(UISlider *)slider {
    self.drawview.progress = slider.value;/*通过滑动UISlider的value值来改变视图中progress的值*/
}

3)实现progress的set方法,并利用CABasicAnimation实现核心动画。

- (void)setProgress:(CGFloat)progress {
    CABasicAnimation * ani = [CABasicAnimation animationWithKeyPath:@"progress"];
    ani.duration = 5.0 * fabs(progress - _progress);
    ani.toValue = @(progress);
    ani.removedOnCompletion = YES;
    ani.fillMode = kCAFillModeForwards;
    ani.delegate = self;
    [self.circleProgressLayer addAnimation:ani forKey:@"progressAni"];
    
    self.progressLabel.text = [NSString stringWithFormat:@"%0.f%%", progress * 100];
    _progress = progress;
    //    self.circleProgressLayer.progress = progress;
    //    [self.circleProgressLayer setNeedsDisplay];
}

4)动画结束将视图中progress的属性传递给了继承CALayer类circleProgressLayer的progress属性

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
    self.circleProgressLayer.progress = self.progress;
}

5)重新绘制drawInContext的方法,这个方法类似于drawRect,但是drawInContext方法不能手动调用(手动调用了也无效),必须通过调用setNeedsDisplay让系统自动调该方法。

- (void)drawInContext:(CGContextRef)ctx {
    CGFloat radius = self.bounds.size.width / 2;
    CGFloat lineWidth = 10.0;
    UIBezierPath * path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(radius, radius) radius:radius - lineWidth / 2 startAngle:0.f endAngle:M_PI * 2 * self.progress clockwise:YES];
    CGContextSetRGBStrokeColor(ctx, 0.5, 0.5, 0.9, 1.0);//笔颜色
    CGContextSetLineWidth(ctx, 10);//线条宽度
    CGContextAddPath(ctx, path.CGPath);
    CGContextStrokePath(ctx);
}

6)重载 needsDisplayForKey方法指定progress属性变化时进行重绘

+ (BOOL)needsDisplayForKey:(NSString *)key {
    if ([key isEqualToString:@"progress"]) {
        return YES;
    }
    return [super needsDisplayForKey:key];
}

参考文献:http://www.jianshu.com/p/673585164bd2

传送门:Demo地址
本人个人微信公众号地址(喜欢记得关注😯)

相关文章

网友评论

    本文标题:IOS之核心动画画圆

    本文链接:https://www.haomeiwen.com/subject/ychrlxtx.html