利用贝塞尔曲线绘制(UIBezierPath)自定义iOS动态速度表,可以自定义刻度,刻度值,进度条样式
使用UIBezierPath画图步骤:
- 创建一个
UIBezierPath对象 - 调用
-moveToPoint:设置初始线段的起点 - 添加线或者曲线去定义一个或者多个子路径
改变UIBezierPath对象跟绘图相关的属性。如,我们可以设置画笔的属性、填充样式等
UIBezierPath创建方法介绍
我们先看看UIBezierPath类提供了哪些创建方式,这些都是工厂方法,直接使用即可。
+ (instancetype)bezierPath;
+ (instancetype)bezierPathWithRect:(CGRect)rect;
+ (instancetype)bezierPathWithOvalInRect:(CGRect)rect;
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect
cornerRadius:(CGFloat)cornerRadius;
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect
byRoundingCorners:(UIRectCorner)corners
cornerRadii:(CGSize)cornerRadii;
+ (instancetype)bezierPathWithArcCenter:(CGPoint)center
radius:(CGFloat)radius
startAngle:(CGFloat)startAngle
endAngle:(CGFloat)endAngle
clockwise:(BOOL)clockwise;
+ (instancetype)bezierPathWithCGPath:(CGPathRef)CGPath;
本文主要是利用下面的方法绘制圆形,进而形成动态的速度表盘形式:
+ (instancetype)bezierPathWithArcCenter:(CGPoint)center
radius:(CGFloat)radius
startAngle:(CGFloat)startAngle
endAngle:(CGFloat)endAngle
clockwise:(BOOL)clockwise;
这个工厂方法用于画弧,参数说明如下:
center: 弧线中心点的坐标radius: 弧线所在圆的半径startAngle: 弧线开始的角度值endAngle: 弧线结束的角度值clockwise: 是否顺时针画弧线
UIBezierPath* outArc=[UIBezierPath bezierPathWithArcCenter:LuCenter radius:self.arcRadius startAngle:startAngle endAngle:endAngle clockwise:YES];
CAShapeLayer* shapeLayer=[CAShapeLayer layer];
shapeLayer.lineWidth=lineWitdth;
shapeLayer.fillColor=filleColor.CGColor;
shapeLayer.strokeColor=strokeColor.CGColor;
shapeLayer.path=outArc.CGPath;
shapeLayer.lineCap=kCALineCapRound;
[self.layer addSublayer:shapeLayer];
CAShapeLayer有着几点很重要(使用CAShapeLayer与UIBezierPath可以实现不在view的drawRect方法中就画出一些想要的图形):
1. 它依附于一个给定的path,必须给与path,而且,即使path不完整也会自动首尾相接
2. strokeStart以及strokeEnd代表着在这个path中所占用的百分比
3. CAShapeLayer动画仅仅限于沿着边缘的动画效果,它实现不了填充效果
下面介绍一下速度表盘的实现过程:
- 画外围弧度
/**
* 画弧度
*
* @param startAngle 开始角度
* @param endAngle 结束角度
* @param lineWitdth 线宽
* @param filleColor 扇形填充颜色
* @param strokeColor 弧线颜色
*/
-(void)drawArcWithStartAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle lineWidth:(CGFloat)lineWitdth fillColor:(UIColor*)filleColor strokeColor:(UIColor*)strokeColor{
//保存弧线宽度,开始角度,结束角度
self.lineWidth=lineWitdth;
self.startAngle=startAngle;
self.endAngle=endAngle;
self.arcAngle=endAngle-startAngle;
self.arcRadius=Calculate_radius;
self.scaleRadius=self.arcRadius-self.lineWidth;
self.scaleValueRadius=self.scaleRadius-self.lineWidth;
self.speedLabel.text=@"0%"; UIBezierPath* outArc=[UIBezierPath bezierPathWithArcCenter:LuCenter radius:self.arcRadius startAngle:startAngle endAngle:endAngle clockwise:YES];
CAShapeLayer* shapeLayer=[CAShapeLayer layer];
shapeLayer.lineWidth=lineWitdth;
shapeLayer.fillColor=filleColor.CGColor;
shapeLayer.strokeColor=strokeColor.CGColor;
shapeLayer.path=outArc.CGPath;
shapeLayer.lineCap=kCALineCapRound;
[self.layer addSublayer:shapeLayer];
} - 绘制刻度,可以实现任意等分
/**
* 画刻度
*
* @param divide 刻度几等分
* @param remainder 刻度数
* @param strokeColor 轮廓填充颜色
* @param fillColor 刻度颜色
*/
-(void)drawScaleWithDivide:(int)divide andRemainder:(NSInteger)remainder strokeColor:(UIColor*)strokeColor filleColor:(UIColor*)fillColor scaleLineNormalWidth:(CGFloat)scaleLineNormalWidth scaleLineBigWidth:(CGFloat)scaleLineBigWidth{ CGFloat perAngle=self.arcAngle/divide;
//我们需要计算出每段弧线的起始角度和结束角度
//这里我们从- M_PI 开始,我们需要理解与明白的是我们画的弧线与内侧弧线是同一个圆心
for (NSInteger i = ; i<= divide; i++) { CGFloat startAngel = (self.startAngle+ perAngle * i);
CGFloat endAngel = startAngel + perAngle/; UIBezierPath *tickPath = [UIBezierPath bezierPathWithArcCenter:LuCenter radius:self.scaleRadius startAngle:startAngel endAngle:endAngel clockwise:YES];
CAShapeLayer *perLayer = [CAShapeLayer layer]; if((remainder!=)&&(i % remainder) == ) {
perLayer.strokeColor = strokeColor.CGColor;
perLayer.lineWidth = scaleLineBigWidth; }else{
perLayer.strokeColor = strokeColor.CGColor;;
perLayer.lineWidth = scaleLineNormalWidth; } perLayer.path = tickPath.CGPath;
[self.layer addSublayer:perLayer]; }
} - 绘制刻度值,刻度值可以按照任意数值等分
/**
* 画刻度值,逆时针设定label的值,将整个仪表切分为N份,每次递增仪表盘弧度的N分之1
*
* @param divide 刻度值几等分
*/
-(void)DrawScaleValueWithDivide:(NSInteger)divide{
CGFloat textAngel =self.arcAngle/divide;
if (divide==) {
return;
}
for (NSUInteger i = ; i <= divide; i++) {
CGPoint point = [self calculateTextPositonWithArcCenter:LuCenter Angle:-(self.endAngle-textAngel*i)];
NSString *tickText = [NSString stringWithFormat:@"%ld%%",(divide - i)*/divide];
//默认label的大小23 * 14
UILabel *text = [[UILabel alloc] initWithFrame:CGRectMake(point.x - , point.y - , , )];
text.text = tickText;
text.font = [UIFont systemFontOfSize:.f];
text.textColor = [UIColor redColor];
text.textAlignment = NSTextAlignmentLeft;
[self addSubview:text];
}
}
//默认计算半径-10,计算label的坐标
- (CGPoint)calculateTextPositonWithArcCenter:(CGPoint)center
Angle:(CGFloat)angel
{
CGFloat x = (self.scaleValueRadius+*self.lineWidth)* cosf(angel);
CGFloat y = (self.scaleValueRadius+*self.lineWidth)* sinf(angel);
return CGPointMake(center.x + x, center.y - y);
} - 进度条曲线
/**
* 进度条曲线
*
* @param fillColor 填充颜色
* @param strokeColor 轮廓颜色
*/
- (void)drawProgressCicrleWithfillColor:(UIColor*)fillColor strokeColor:(UIColor*)strokeColor{
UIBezierPath *progressPath = [UIBezierPath bezierPathWithArcCenter:LuCenter radius:self.arcRadius startAngle:self.startAngle endAngle:self.endAngle clockwise:YES];
CAShapeLayer *progressLayer = [CAShapeLayer layer];
self.progressLayer = progressLayer;
progressLayer.lineWidth = self.lineWidth+0.25f;
progressLayer.fillColor = fillColor.CGColor;
progressLayer.strokeColor = strokeColor.CGColor;
progressLayer.path = progressPath.CGPath;
progressLayer.strokeStart = ;
progressLayer.strokeEnd = 0.0;
progressLayer.lineCap=kCALineCapRound;
[self.layer addSublayer:progressLayer];
} - 为进度条添加渐变图层,图层颜色是从左向右渐变
/**
* 添加渐变图层
*
* @param colorGradArray 颜色数组,如果想达到红-黄-红效果,数组应该是红,黄,红
*/
-(void)setColorGrad:(NSArray*)colorGradArray{
//渐变图层
CALayer *gradientLayer = [CALayer layer];
CAGradientLayer *gradientLayer1 = [CAGradientLayer layer];
//增加渐变图层,frame为当前layer的frame
gradientLayer1.frame = CGRectMake(, , self.bounds.size.width, self.bounds.size.height);
[gradientLayer1 setColors:colorGradArray];
[gradientLayer1 setStartPoint:CGPointMake(, )];
[gradientLayer1 setEndPoint:CGPointMake(, )];
[gradientLayer addSublayer:gradientLayer1]; [gradientLayer setMask:_progressLayer]; //用progressLayer来截取渐变层
[self.layer addSublayer:gradientLayer];
}个人写代码喜欢添加注释,可是在奈何文笔不行,表达不清,请移步到我的GitHub上下载Demo,如果有什么问题也可以给我发邮件,评论探讨。

利用贝塞尔曲线绘制(UIBezierPath)自定义iOS动态速度表,可以自定义刻度,刻度值,进度条样式的更多相关文章
- JavaScript+canvas 利用贝塞尔曲线绘制曲线
效果图: <body> <canvas id="test" width="800" height="300">< ...
- iOS 使用贝塞尔曲线绘制路径
使用贝塞尔曲线绘制路径 大多数时候,我们在开发中使用的控件的边框是矩形,或者做一点圆角,是使得矩形的角看起来更加的圆滑. 但是如果我们想要一个不规则的图形怎么办?有人说,叫UI妹子做,不仅省事,还可以 ...
- OpenGL 实践之贝塞尔曲线绘制
说到贝塞尔曲线,大家肯定都不陌生,网上有很多关于介绍和理解贝塞尔曲线的优秀文章和动态图. 以下两个是比较经典的动图了. 二阶贝塞尔曲线: 三阶贝塞尔曲线: 由于在工作中经常要和贝塞尔曲线打交道,所以简 ...
- n阶贝塞尔曲线绘制(C/C#)
原文:n阶贝塞尔曲线绘制(C/C#) 贝塞尔是很经典的东西,轮子应该有很多的.求n阶贝塞尔曲线用到了 德卡斯特里奥算法(De Casteljau's Algorithm) 需要拷贝代码请直接使用本文最 ...
- 基于canvas二次贝塞尔曲线绘制鲜花
canvas中二次贝塞尔曲线参数说明: cp1x:控制点1横坐标 cp1y:控制点1纵坐标 x: 结束点1横坐标 y:结束点1纵坐标 cp2x:控制点2横坐标 cp2y:控制点2纵坐标 z:结束点2横 ...
- 最简单的android自定义进度条样式
一.自定义圆形进度条样式 1.在安卓项目drawable目录下新建一个xml文件如下:<?xml version="1.0" encoding="utf-8&quo ...
- iOS贝塞尔曲线(UIBezierPath)的基本使用方法
简介 UIBezierPath是对Core Graphics框架的一个封装,使用UIBezierPath类我们可以画出圆形(弧线)或者多边形(比如:矩形)等形状,所以在画复杂图形的时候会经常用到. 分 ...
- iOS:使用贝塞尔曲线绘制图表(折线图、柱状图、饼状图)
1.介绍: UIBezierPath :画贝塞尔曲线的path类 UIBezierPath定义 : 贝赛尔曲线的每一个顶点都有两个控制点,用于控制在该顶点两侧的曲线的弧度. 曲线的定义有四个点:起始点 ...
- 贝塞尔曲线(UIBezierPath)属性、方法汇总
UIBezierPath主要用来绘制矢量图形,它是基于Core Graphics对CGPathRef数据类型和path绘图属性的一个封装,所以是需要图形上下文的(CGContextRef),所以一般U ...
随机推荐
- Centos6.8更好yum源
第一步:备份你的原镜像文件,以免出错后可以恢复. mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.back ...
- MYSQL初级学习笔记五:连接查询!(视频序号:初级_37-41)
知识点七:连接查询(37-41) 什么是连接查询: 连接查询是将两个或两个以上的表按某个条件连接起来,从中选取需要的数据.连接查询是同时查询两个或两个以上的表时使用的.当不同的表中存在相同意义的字段时 ...
- HDU - 1269 迷宫城堡(有向图的强连通分量)
d.看一个图是不是强连通图 s.求出强连通分量,看看有没有一个强连通分量包含所有点. c.Tarjan /* Tarjan算法 复杂度O(N+M) */ #include<iostream> ...
- 安装程序工具 (Installutil.exe)22
网址:https://msdn.microsoft.com/zh-cn/library/50614e95(VS.80).aspx 安装程序工具 (Installutil.exe) .NET Fram ...
- magento导入数据的方法
导入演示数据 分两种情况处理. 如果你是用composer方式安装的 非常简单,二行命令搞定:在项目根目录下执行.我们的是在/var/www/magento2/下面. 安装演示数据 php bin/m ...
- Opencv实现简易播放器
实现了在MFC中显示图片,再要显示一个视频就是轻而易举的事了,本篇介绍使用Opencv制作一个简易的播放器,实现打开文件.暂停.继续播放.再次播放和总\当前帧数显示功能. 首先还是先看一下界面效果: ...
- 安装YCM出现:YouCompleteMe unavailable no module named frozendict或者 YouCompleteMe unavailable no module named future
参考博文:http://blog.sina.com.cn/s/blog_8f70642d0102wo57.html 原因就是你或者没用Vundle安装,或者Vundle由于网速太慢下载到一半不能把安装 ...
- BZOJ_1915_[Usaco2010 Open]奶牛的跳格子游戏_DP+单调队列
BZOJ_1915_[Usaco2010 Open]奶牛的跳格子游戏_DP+单调队列 Description 奶牛们正在回味童年,玩一个类似跳格子的游戏,在这个游戏里,奶牛们在草地上画了一行N个格子, ...
- 【AHOI2009】中国象棋
[题目链接] 点击打开链接 [算法] 动态规划 f[i][j][k]表示前i行,有j列放了1个,有k列放了两个 分六种情况讨论即可 [代码] #include<bits/stdc++.h> ...
- cmake官方文档
https://cmake.org/cmake/help/v3.0/genindex.html