![](https://img.haomeiwen.com/i1540977/494889faee2fd326.png)
目录
一、首先我们需要画一个圆
实现方法、下面通过三种方式进行绘制圆 分别为1、贝塞尔曲线绘制 2、CGPathRef绘制 3、CGContextRef绘制
二、利用系统UISlider的滑动事件和核心动画CABasicAnimation对圆弧度的变化做到实时监听
实现方法:(1)实现UISlider的滑动事件(2)创建类继承CALayer来实现核心动画(3)在视图中通过传递属性的方式,实时更改绘制圆的角度,从而实现UISlider对圆弧度的监听
三、将随时更改弧度的变化值赋值到label上,实现百分比效果。
![](https://img.haomeiwen.com/i1540977/2e135b654972a32d.gif)
一、绘制一个圆
//方法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地址
本人个人微信公众号地址(喜欢记得关注😯)
![](https://img.haomeiwen.com/i1540977/713b2dd011ac7b71.jpg)
网友评论