如何在IOS开发中实现自定义仪表盘
来源:爱站网时间:2020-10-04编辑:网友分享
自定义仪表盘,相信大家都接触过很多,相信最多的应该也是汽车油耗这些方面的开发,今天这篇文章是爱站技术频道小编带给大家的如何在IOS开发中实现自定义仪表盘,一起跟随小编过来看看吧。
自定义仪表盘,相信大家都接触过很多,相信最多的应该也是汽车油耗这些方面的开发,今天这篇文章是爱站技术频道小编带给大家的如何在IOS开发中实现自定义仪表盘,一起跟随小编过来看看吧。
今天给大家带来一个自定义的仪表盘,效果图如下。
Demo中用到了 QuartzCore类 首先继承一个UIView。
// Gauge.h // GaugeDemo // // Created by 海锋 周 on 12-3-27. // Copyright (c) 2012年 CJLU rights reserved. // #import#import @interface Gauge : UIView { UIImage *gaugeView; UIImageView *pointer; CGFloat maxNum; CGFloat minNum; CGFloat maxAngle; CGFloat minAngle; CGFloat gaugeValue; CGFloat gaugeAngle; CGFloat angleperValue; CGFloat scoleNum; NSMutableArray *labelArray; CGContextRef context; } @property (nonatomic,retain) UIImage *gaugeView; @property (nonatomic,retain) UIImageView *pointer; @property (nonatomic,retain) NSMutableArray *labelArray; @property (nonatomic) CGContextRef context; -(void)setGaugeValue:(CGFloat)value animation:(BOOL)isAnim; @end
指针的旋转是通过QuartzCore.framework中的CATransform3DRotate 来实现的,所以一定要记得把框架添加进来。当然在旋转之前,我们还需要把指针的中心pointer.layer.anchorPoint 移动到你需要的转动中心。
在设置旋转动画的时候,我们用的不是CABaseAnimiation 而是用 CAKeyframeAnimation。这是因为如果使用中的 toValue 来实现旋转的话,它默认是以最小的旋转的,如果要实现控制旋转的方向的话,我们就只能用关键帧来设置旋转的路径。用关键帧的好处还有一个,就是可以给指针添加,旋转到指定位置以后的左右摆动的效果。
绘制仪表盘是通过Quartz2D来实现的,首先我们需要用UIGraphicsGetCurrentContext函数来获取一个Context上下文,就是相当于获取一个画布。然后就可以在上面通过三角函数的计算,画出背景图片,和上面的刻度线了。
// Gauge.m // GaugeDemo // // Created by 海锋 周 on 12-3-27. // Copyright (c) 2012年 CJLU. All rights reserved. // #import "Gauge.h" #import#define MAXOFFSETANGLE 120.0f #define POINTEROFFSET 90.0f #define MAXVALUE 120.0f #define CELLMARKNUM 5 #define CELLNUM 12 #define GAUGESTRING @"单位:Km/h" #define DEFLUATSIZE 300 /************************************************ 仪表盘的大小不建议设置的太小。 长宽都是300是最适合的 如果要更小的需要自行修改刻度长度和文字大小 ---powered by 周海锋 2012-3-29 ***********************************************/ @implementation Gauge @interface Gauge (private) - (CGFloat) parseToX:(CGFloat) radius Angle:(CGFloat)angle; - (CGFloat) parseToY:(CGFloat) radius Angle:(CGFloat)angle; - (CGFloat) transToRadian:(CGFloat)angel; - (CGFloat) parseToAngle:(CGFloat) val; - (CGFloat) parseToValue:(CGFloat) val; - (void)setTextLabel:(NSInteger)labelNum; - (void)setLineMark:(NSInteger)labelNum; - (void) pointToAngle:(CGFloat) angle Duration:(CGFloat) duration; @end @synthesize gaugeView,pointer,context; @synthesize labelArray; - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { //设置背景透明 [self setBackgroundColor:[UIColor clearColor]]; scoleNum = DEFLUATSIZE/frame.size.width; maxNum = MAXVALUE; minNum = 0.0f; minAngle = -MAXOFFSETANGLE; maxAngle = MAXOFFSETANGLE; gaugeValue = 0.0f; gaugeAngle = -MAXOFFSETANGLE; angleperValue = (maxAngle - minAngle)/(maxNum - minNum); gaugeView= [UIImage imageNamed:@"gaugeback.png"]; //添加指针 UIImage *_pointer = [UIImage imageNamed:@"pointer2.png"]; pointer = [[UIImageView alloc] initWithImage:_pointer]; pointer.layer.anchorPoint = CGPointMake(0.5, 0.78); pointer.center = self.center; pointer.transform = CGAffineTransformMakeScale(scoleNum, scoleNum); [self addSubview:pointer]; //设置文字标签 [self setTextLabel:CELLNUM]; //设置指针到0位置 pointer.layer.transform = CATransform3DMakeRotation([self transToRadian:-MAXOFFSETANGLE], 0, 0, 1); } return self; } /* * setTextLabel 绘制刻度值 * @labelNum NSInteger 刻度值的数目 */ -(void)setTextLabel:(NSInteger)labelNum { labelArray = [NSMutableArray arrayWithCapacity:labelNum]; CGFloat textDis = (maxNum - minNum)/labelNum; CGFloat angelDis = (maxAngle - minAngle)/labelNum; CGFloat radius = (self.center.x - 75)*scoleNum; CGFloat currentAngle; CGFloat currentText = 0.0f; CGPoint centerPoint = self.center; for(int i=0;ilabelNum*2/3) { CGContextSetStrokeColorWithColor(context, [[UIColor colorWithRed:1 green:0 blue:0 alpha:0.8] CGColor]); }else if(i>labelNum*1/3){ CGContextSetStrokeColorWithColor(context, [[UIColor colorWithRed:1 green:1 blue:0 alpha:0.8] CGColor]); }else{ CGContextSetStrokeColorWithColor(context, [[UIColor colorWithRed:0 green:1 blue:0 alpha:0.8] CGColor]); } //绘制不同的长短的刻度 if(i%5==0) { CGContextSetLineCap(context, kCGLineCapSquare); CGContextSetLineWidth(context, 3); CGContextStrokePath(context); CGContextMoveToPoint(context,centerPoint.x+[self parseToX:radius-25*scoleNum Angle:currentAngle], centerPoint.y+[self parseToY:radius-25*scoleNum Angle:currentAngle]); CGContextAddLineToPoint(context,centerPoint.x+[self parseToX:radius-65*scoleNum Angle:currentAngle], centerPoint.y+[self parseToY:radius-65*scoleNum Angle:currentAngle]); }else{ CGContextSetLineWidth(context, 2); CGContextSetLineCap(context, kCGLineCapSquare); CGContextStrokePath(context); CGContextMoveToPoint(context,centerPoint.x+[self parseToX:radius-25*scoleNum Angle:currentAngle], centerPoint.y+[self parseToY:radius-25*scoleNum Angle:currentAngle]); CGContextAddLineToPoint(context,centerPoint.x+[self parseToX:radius-40*scoleNum Angle:currentAngle], centerPoint.y+[self parseToY:radius-40*scoleNum Angle:currentAngle]); } } } /* * setGaugeValue 移动到某个数值 * @value CGFloat 移动到的数值 * @isAnim BOOL 是否执行动画 */ -(void)setGaugeValue:(CGFloat)value animation:(BOOL)isAnim { CGFloat tempAngle = [self parseToAngle:value]; gaugeValue = value; //设置转动时间和转动动画 if(isAnim){ [self pointToAngle:tempAngle Duration:0.6f]; }else { [self pointToAngle:tempAngle Duration:0.0f]; } } /* * pointToAngle 按角度旋转 * @angel CGFloat 角度 * @duration CGFloat 动画执行时间 */ - (void) pointToAngle:(CGFloat) angle Duration:(CGFloat) duration { CAKeyframeAnimation *anim=[CAKeyframeAnimation animationWithKeyPath:@"transform"]; NSMutableArray *values=[NSMutableArray array]; anim.duration = duration; anim.autoreverses = NO; anim.fillMode = kCAFillModeForwards; anim.removedOnCompletion= NO; CGFloat distance = angle/10; //设置转动路径,不能直接用 CABaseAnimation 的toValue,那样是按最短路径的,转动超过180度时无法控制方向 int i = 1; for(;imaxNum){ return maxNum; } CGFloat temp =(val-gaugeValue)*angleperValue; return temp; } /* * parseToValue 根据角度计算数值 * @val CGFloat 要移动到的角度 */ -(CGFloat) parseToValue:(CGFloat) val { CGFloat temp=val/angleperValue; CGFloat temp2=maxNum/2+temp; if(temp2>maxNum){ return maxNum; }else if(temp2
对于如何在IOS开发中实现自定义仪表盘,相信诸多开发者心中已经有数了,如果还有疑问,建议收藏js.aizhan.com学习更多知识吧。