先看下效果:
功能:
支持設(shè)置表盤(pán)最大值蜕琴,表盤(pán)動(dòng)畫(huà)注整,指針指向,顏色漸變能曾。
1.畫(huà)基本結(jié)構(gòu)弯蚜,包括灰色環(huán)曙旭、漸變夜色,箭頭和內(nèi)層虛線雏搂。
- (instancetype)initWithFrame:(CGRect)frame
{
? ? if (self = [super initWithFrame:frame]) {
? ? ? ? [self createSubLayers];
? ? ? ? [self addSubview:self.currentRateLabel];
? ? ? ? self.backgroundColor = [UIColor blackColor];
? ? }
? ? return self;
}
- (void)createSubLayers
{
? ? //外層環(huán)
? ? UIBezierPath *grayPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(Radius+LineWidth/2, self.frame.size.height) radius:Radius startAngle:M_PI endAngle:0 clockwise:YES];
? ? self.arcLayer = [CAShapeLayer layer];
? ? self.arcLayer.path = grayPath.CGPath;
? ? self.arcLayer.lineWidth = LineWidth;
? ? self.arcLayer.strokeColor = [UIColor lightGrayColor].CGColor;
//? ? [self.layer addSublayer:self.arcLayer];
? ? self.arcLayer.fillColor = [UIColor clearColor].CGColor;
? ? CAShapeLayer *grayLayer = [CAShapeLayer layer];
? ? grayLayer.path = grayPath.CGPath;
? ? grayLayer.lineWidth = LineWidth;
? ? grayLayer.strokeColor = [UIColor lightGrayColor].CGColor;
? ? grayLayer.fillColor = [UIColor clearColor].CGColor;
? ? [self.layer addSublayer:grayLayer];
? ? //漸變色
? ? CALayer *gradientLayer = [CALayer layer];
? ? CAGradientLayer *gradientLayer1 = [CAGradientLayer layer];
? ? gradientLayer1.frame = CGRectMake(0, 0, self.frame.size.width/2, self.frame.size.height);
? ? [gradientLayer1 setColors:[NSArray arrayWithObjects:(id)[[UIColor redColor] CGColor],(id)[[UIColor colorWithRed:255/255.0 green:220/255.0 blue:2/255.0 alpha:1.0] CGColor], nil]];
? ? [gradientLayer1 setLocations:@[@0.1,@0.9]];
? ? [gradientLayer1 setStartPoint:CGPointMake(0 ,1)];
? ? [gradientLayer1 setEndPoint:CGPointMake(1, 0)];
? ? [gradientLayer addSublayer:gradientLayer1];
? ? CAGradientLayer *gradientLayer2 = [CAGradientLayer layer];
? ? [gradientLayer2 setLocations:@[@0.1,@0.9]];
? ? gradientLayer2.frame = CGRectMake(self.frame.size.width/2, 0, self.frame.size.width/2, self.frame.size.height);
? ? [gradientLayer2 setColors:[NSArray arrayWithObjects:(id)[[UIColor colorWithRed:255/255.0 green:220/255.0 blue:2/255.0 alpha:1.0] CGColor],(id)[UIColor greenColor].CGColor, nil]];
? ? [gradientLayer2 setStartPoint:CGPointMake(0, 0)];
? ? [gradientLayer2 setEndPoint:CGPointMake(1, 1)];
? ? [gradientLayer addSublayer:gradientLayer2];
? ? [gradientLayer setMask:self.arcLayer];
? ? [self.layer addSublayer:gradientLayer];
? ? //虛線
? ? UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(Radius+LineWidth/2, self.frame.size.height) radius:Radius/2 startAngle:M_PI endAngle:0 clockwise:YES];
? ? CAShapeLayer *dashLayer = [CAShapeLayer layer];
? ? dashLayer.lineWidth = 1.0;
? ? dashLayer.strokeColor = [UIColor grayColor].CGColor;
? ? dashLayer.fillColor = [UIColor clearColor].CGColor;
? ? dashLayer.path = path.CGPath;
? ? [dashLayer setLineDashPattern:@[@(2),@(3)]];
? ? [self.layer addSublayer:dashLayer];
? ? //箭頭
? ? self.pointerLayer = [CAShapeLayer layer];
? ? self.pointerLayer.strokeColor = [UIColor grayColor].CGColor;
? ? self.pointerLayer.fillColor = [UIColor grayColor].CGColor;
? ? self.pointerLayer.lineWidth = 0.5;
? ? [self.layer addSublayer:self.pointerLayer];
}
2.表盤(pán)刻度根據(jù)外部參數(shù)(最大值)來(lái)確定椒袍,所以每次跳整最大值驼唱,表盤(pán)刻度會(huì)發(fā)生變化。
- (void)setTotal:(CGFloat)total
{
? ? _total = total;
? ? //添加坐標(biāo)
? ? NSUInteger floorTotal = floor(total);
? ? NSUInteger puer = 0,coordinateNum = 0;
? ? if (floorTotal == 0) {
? ? }else if (floorTotal <= 4 && floorTotal >= 1){
? ? ? ? puer = 1;
? ? ? ? coordinateNum = floorTotal;
? ? }else if (floorTotal <= 16 && floorTotal > 4){
? ? ? ? puer = floorTotal/4;
? ? ? ? coordinateNum = 4;
? ? }else if (floorTotal < 40 && floorTotal >= 16){
? ? ? ? puer = 10;
? ? ? ? coordinateNum = floorTotal/10;
? ? }else if (floorTotal < 100 && floorTotal >= 40){
? ? ? ? puer = floorTotal/40*10;
? ? ? ? coordinateNum = 4;
? ? }else if (floorTotal < 400 && floorTotal >= 100){
? ? ? ? puer = 100;
? ? ? ? coordinateNum = floorTotal/100;
? ? }else if (floorTotal <= 1000 && floorTotal >= 400){
? ? ? ? puer = floorTotal/400*100;
? ? ? ? coordinateNum = 4;
? ? }else{
? ? }
? ? //表盤(pán)刻度
? ? for (NSUInteger i = 0; i< coordinateNum + 1; i++) {
? ? ? ? CGFloat startX = self.frame.size.width/2 - Radius*cos(M_PI*puer*i/total);
? ? ? ? CGFloat startY = self.frame.size.height - Radius*sin(M_PI*puer*i/total);
? ? ? ? UIBezierPath *path = [UIBezierPath bezierPath];
? ? ? ? [path moveToPoint:CGPointMake(startX, startY)];
? ? ? ? [path addLineToPoint:CGPointMake(self.frame.size.width/2 - (Radius+15)*cos(M_PI*puer*i/total), self.frame.size.height - (Radius+15)*sin(M_PI*puer*i/total))];
? ? ? ? CAShapeLayer *layer = [CAShapeLayer layer];
? ? ? ? layer.lineWidth = 2.0;
? ? ? ? layer.strokeColor = [UIColor whiteColor].CGColor;
? ? ? ? layer.path = path.CGPath;
? ? ? ? [self.layer addSublayer:layer];
? ? ? ? //小刻度
? ? ? ? CGFloat angle = M_PI*puer/total;
? ? ? ? for (NSUInteger j = 0; j < 9; j++) {
? ? ? ? ? ? CGFloat startX0 = self.frame.size.width/2 - (Radius+15)*cos(M_PI*puer*i/total + angle*j/10.0);
? ? ? ? ? ? CGFloat startY0 = self.frame.size.height - (Radius+15)*sin(M_PI*puer*i/total + angle*j/10.0);
? ? ? ? ? ? CGFloat toX = self.frame.size.width/2 - (Radius +8)*cos(M_PI*puer*i/total + angle*j/10.0);
? ? ? ? ? ? CGFloat toY = self.frame.size.height - (Radius +8)*sin(M_PI*puer*i/total + angle*j/10.0);
? ? ? ? ? ? UIBezierPath *path0 = [UIBezierPath bezierPath];
? ? ? ? ? ? [path0 moveToPoint:CGPointMake(startX0, startY0)];
? ? ? ? ? ? [path0 addLineToPoint:CGPointMake(toX, toY)];
? ? ? ? ? ? CAShapeLayer *layer0 = [CAShapeLayer layer];
? ? ? ? ? ? layer0.path = path0.CGPath;
? ? ? ? ? ? layer0.lineWidth = 1.0;
? ? ? ? ? ? layer0.strokeColor = [UIColor whiteColor].CGColor;
? ? ? ? ? ? [self.layer addSublayer:layer0];
? ? ? ? }
? ? }
? ? CGFloat r = Radius-25;
? ? for (NSInteger i = 0; i< coordinateNum + 1; i++) {
? ? ? ? //如果最后一個(gè)和totalLabel距離太近驹暑,去掉
? ? ? ? if (M_PI*puer*i/total < M_PI*9/10) {
? ? ? ? ? ? CGFloat positionX = self.frame.size.width/2 - r*cos(M_PI*puer*i/total);
? ? ? ? ? ? CGFloat positionY = self.frame.size.height - r*sin(M_PI*puer*i/total);
? ? ? ? ? ? UILabel *coordinateLabel = [[UILabel alloc]init];
? ? ? ? ? ? coordinateLabel.textColor = [UIColor colorWithRed:0.2 green:0.5 blue:0.8 alpha:1.0];
? ? ? ? ? ? coordinateLabel.textAlignment = NSTextAlignmentCenter;
? ? ? ? ? ? coordinateLabel.frame = CGRectMake(positionX,positionY , 38, 20);
? ? ? ? ? ? coordinateLabel.text = [NSString stringWithFormat:@"%ld",puer*i];
? ? ? ? ? ? coordinateLabel.font = [UIFont systemFontOfSize:12];
? ? ? ? ? ? coordinateLabel.center = CGPointMake(positionX, positionY);
? ? ? ? ? ? [self addSubview:coordinateLabel];
? ? ? ? }
? ? }
? ? UILabel *totalLabel = [[UILabel alloc]init];
? ? totalLabel.textColor = [UIColor colorWithRed:0.2 green:0.5 blue:0.8 alpha:1.0];
? ? totalLabel.textAlignment = NSTextAlignmentCenter;
? ? totalLabel.frame = CGRectMake(Radius*2-30-20, self.frame.size.height - 10, 50, 20);
? ? totalLabel.center = CGPointMake(self.frame.size.width/2 + r, self.frame.size.height);
? ? totalLabel.text = [NSString stringWithFormat:@"%.1f",total];
? ? totalLabel.font = [UIFont systemFontOfSize:12];
? ? [self addSubview:totalLabel];
}
3.當(dāng)前值用來(lái)確定箭頭指向玫恳。
- (void)setCurrentValue:(CGFloat)currentValue
{
? ? _currentValue = currentValue;
? ? CGFloat rote = currentValue/_total;
? ? _currentRateLabel.text = [NSString stringWithFormat:@"%.1f",currentValue];
? ? _currentRateLabel.textColor = [self getBgColor:MIN(floor(50*rote), 50)];
? ? //動(dòng)畫(huà)
? ? CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
? ? [animation setDuration:3.0];
? ? animation.fromValue = @0.0;
? ? animation.toValue = @(rote);
? ? animation.removedOnCompletion = NO;
? ? animation.fillMode = kCAFillModeForwards;
? ? animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
? ? [self.arcLayer addAnimation:animation forKey:@"strokeEnd"];
? ? //調(diào)整箭頭位置
? ? CGFloat arrorAngle = rote*M_PI;
? ? CGFloat startPointX = self.frame.size.width/2 - (Radius/2-15)*cos(arrorAngle);
? ? CGFloat startPointY = self.frame.size.height - (Radius/2-15)*sin(arrorAngle);
? ? CGFloat pointX1 = startPointX - ArrorWidth*cos(arrorAngle);
? ? CGFloat pointY1 = startPointY - ArrorWidth*sin(arrorAngle);
? ? CGFloat pointX2 = pointX1 - 3*sin(arrorAngle);
? ? CGFloat pointY2 = pointY1 + 3*cos(arrorAngle);
? ? CGFloat pointX3 = pointX1 + sin(arrorAngle) - 10*cos(arrorAngle);
? ? CGFloat pointY3 = pointY1 - cos(arrorAngle) - 10*sin(arrorAngle);
? ? CGFloat pointX4 = pointX1 + 5*sin(arrorAngle);
? ? CGFloat pointY4 = pointY1 - 5*cos(arrorAngle);
? ? CGFloat pointX5 = pointX1 + 2*sin(arrorAngle);
? ? CGFloat pointY5 = pointY1 - 2*cos(arrorAngle);
? ? CGFloat pointX6 = startPointX + 2*sin(arrorAngle);
? ? CGFloat pointY6 = startPointY - 2*cos(arrorAngle);
? ? UIBezierPath *pointPath = [UIBezierPath bezierPath];
? ? [pointPath moveToPoint:CGPointMake(startPointX, startPointY)];
? ? [pointPath addLineToPoint:CGPointMake(pointX1, pointY1)];
? ? [pointPath addLineToPoint:CGPointMake(pointX2, pointY2)];
? ? [pointPath addLineToPoint:CGPointMake(pointX3, pointY3)];
? ? [pointPath addLineToPoint:CGPointMake(pointX4, pointY4)];
? ? [pointPath addLineToPoint:CGPointMake(pointX5, pointY5)];
? ? [pointPath addLineToPoint:CGPointMake(pointX6, pointY6)];
? ? [pointPath closePath];
? ? self.pointerLayer.path = pointPath.CGPath;
}
4.最后,顯示表盤(pán)指示的值(字體顏色會(huì)變)
- (UIColor *)getBgColor:(NSUInteger)index
{
? ? int r=0,g=0,b=0;
//? ? r = 255-255.0/50*index;
//? ? g = 255.0/50*index;
? ? float one = (255 + 255) / 60;//(255+255)除以最大取值的三分之二
? ? if (index < 30)//第一個(gè)三等分
? ? {
? ? ? ? r = 255;
? ? ? ? g = (int)(one * index);
? ? }
? ? else if (index >= 30 && index < 60)//第二個(gè)三等分
? ? {
? ? ? ? r =? 255 - (int)((index - 30) * one);//val減最大取值的三分之一;
? ? ? ? g = 255;
? ? }
? ? else { g = 255; }//最后一個(gè)三等分
? ? return [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0];
}
- (UILabel *)currentRateLabel
{
? ? if (!_currentRateLabel) {
? ? ? ? _currentRateLabel = [[UILabel alloc]initWithFrame:CGRectMake(self.frame.size.width/2 - 40, self.frame.size.height - 30, 80, 30)];
? ? ? ? _currentRateLabel.font = [UIFont systemFontOfSize:18];
? ? ? ? _currentRateLabel.textAlignment = NSTextAlignmentCenter;
? ? }
? ? return _currentRateLabel;
}
外部調(diào)用:
DashBoard *dashBoard = [[DashBoard alloc]initWithFrame:CGRectMake(30, 100, 300, 150)];
? ? dashBoard.total = 50;
? ? dashBoard.currentValue = 43;
? ? [self.view addSubview:dashBoard];