手把手教你玩转iOS的仪表盘

手把手教你玩转iOS的仪表盘

最近公司项目需求,要求我做一个仪表盘,指针能工具报警值变换指针颜色的那种。而且仪表盘的量程,报警值都是不一样的(ps:仪表盘个数有点多,几十个的样子,而且每个都不一样)。刚开始的时候,万恶的美工告诉我说,每个仪表盘的度数、报警值是一样的,我就贴了一张图片,指针到了报警值就换图片。后来又告诉我说仪表盘是不一样的(内心orz:内心一万只cnm奔腾)

好吧,废话不多说了,直入主题。

我使用UIView的- (void)drawRect:(CGRect)rect方法画的,首先当然就是使用贝塞尔曲线描出两条路径,路径的颜色通过传参的方式传过来
“` python
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetShadow(context, CGSizeMake(0, 0), 0);

UIBezierPath *path = [UIBezierPath bezierPath];
[path addArcWithCenter:CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2) radius:76 startAngle:ANGLE_TO_RADIANS(150) endAngle:ANGLE_TO_RADIANS(390) clockwise:YES];
UIColor *color  = self.leftColor;
[color setStroke];
path.lineWidth = 20;
[path stroke];

UIBezierPath *path2 = [UIBezierPath bezierPath];
[path2 addArcWithCenter:CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2) radius:76 startAngle:ANGLE_TO_RADIANS(150 + ((self.warningValue)/(self->maxValue - self->minValue))*240) endAngle:ANGLE_TO_RADIANS(390) clockwise:YES];
UIColor *color2 = self.rightColor;
[color2 setStroke];
path2.lineWidth = 20;
[path2 stroke];

这些都是次要的,因为iOS开发的基本都会这个吧,那我还贴代码,我是不是多此一举。。。。。。

其实最主要的当然就是画仪表盘的刻度了,这里有两个重要的方法
CGContextTranslateCTM(context, center_.x, center_.y);
CGContextRotateCTM(context, angle);
第一个是移动函数,将图形上下文的原点在X轴和Y轴方向移动到某个位置,这里我要不要科普一下X轴和Y轴呢??感觉多次一举吧,因为平时开发中设置视图的frame的时候经常使用到呢,原点就是屏幕的左上角了,原点往右就是X轴正方向,原点往下就是Y轴正方向,原点朝正对我我们的方向就是Z轴的正方向了。是不是很脑残的解释哈。。。
第二个是旋转函数,将图像上下文绕原点旋转angle度。画仪表的刻度就靠他了。
CGFloat allAngle = 0.0;
CGFloat cenx = CGRectGetMidX(self.bounds);
CGFloat ceny = CGRectGetMidY(self.bounds);
[self rotateContext:context fromCenter:CGPointMake(cenx, ceny) withAngle:ANGLE_TO_RADIANS(174+90)];
for(int i = 0; i < (8+1); i++)
{
CGContextSetStrokeColorWithColor(context, [UIColor whiteColor].CGColor);
CGContextSetLineWidth(context, 2.0);
CGContextMoveToPoint(context, self.bounds.size.width/2, 0);
CGContextAddLineToPoint(context, self.bounds.size.width/2, 20);
CGContextStrokePath(context);
[self rotateContext:context fromCenter:CGPointMake(cenx, ceny) withAngle:ANGLE_TO_RADIANS((276-84)/8)];
}
//旋转了角度,画完刻度需要将坐标旋转回初始状态
allAngle = ANGLE_TO_RADIANS((276-84)/8)*(8+1);
[self rotateContext:context fromCenter:CGPointMake(cenx, ceny) withAngle:-ANGLE_TO_RADIANS(150+24+90)];
[self rotateContext:context fromCenter:CGPointMake(cenx, ceny) withAngle:-allAngle];

  • (void)rotateContext:(CGContextRef)context fromCenter:(CGPoint)center_ withAngle:(CGFloat)angle
    {
    CGContextTranslateCTM(context, center_.x, center_.y);
    CGContextRotateCTM(context, angle);
    CGContextTranslateCTM(context, -center_.x, -center_.y);
    }
    这样刻度就换好了,然后加一个指针就可以了,这里的指针就没有自己画了,直接贴了一张图,然后找准锚点和位置,再加一个定时器CADisplayLink,让定时器每次都转一刻度就哦了。这样就有人会有疑惑了,那么我想转快点咋办呢???如果每次转多点度数的话,那么必然导致转的不准啊。。。。。。这还不好解决吗?前面转的快点,当转的度数快到目标度数时,我又换成每次转一度,不就完美解决了。
    最后一个就是刻度的问题了,用我们的三角函数和半径,将一个数组填进去就好了。
    for (NSInteger i = 0; i < _numArray.count; i++) {
    static CGFloat r = 55;
    CGFloat x = 75 + r*cosf(ANGLE_TO_RADIANS(210-24*i));
    CGFloat y = 75 - r*sinf(ANGLE_TO_RADIANS(210-24*i));
    UILabel *numLabel = [[UILabel alloc]initWithFrame:CGRectMake(x, y, 40, 20)];
    numLabel.font = [UIFont systemFontOfSize:12];
    numLabel.textAlignment = NSTextAlignmentLeft;
    numLabel.text = [NSString stringWithFormat:@”%@”,_numArray[i]];
    [self addSubview:numLabel];
    }

上传两张效果图
这里写图片描述
这里写图片描述

猜你喜欢

转载自blog.csdn.net/darrenzzb66/article/details/52511077
今日推荐