ios制作一個(gè)簡(jiǎn)單的儀表盤(pán)

先看下效果:


功能:

支持設(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];

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末岗钩,一起剝皮案震驚了整個(gè)濱河市纽窟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌兼吓,老刑警劉巖臂港,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異视搏,居然都是意外死亡审孽,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)浑娜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)佑力,“玉大人,你說(shuō)我怎么就攤上這事筋遭〈虿” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵漓滔,是天一觀的道長(zhǎng)编饺。 經(jīng)常有香客問(wèn)我,道長(zhǎng)响驴,這世上最難降的妖魔是什么透且? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮豁鲤,結(jié)果婚禮上秽誊,老公的妹妹穿的比我還像新娘鲸沮。我一直安慰自己,他們只是感情好锅论,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布讼溺。 她就那樣靜靜地躺著,像睡著了一般棍厌。 火紅的嫁衣襯著肌膚如雪肾胯。 梳的紋絲不亂的頭發(fā)上竖席,一...
    開(kāi)封第一講書(shū)人閱讀 51,631評(píng)論 1 305
  • 那天耘纱,我揣著相機(jī)與錄音,去河邊找鬼毕荐。 笑死束析,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的憎亚。 我是一名探鬼主播员寇,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼第美!你這毒婦竟也來(lái)了蝶锋?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤什往,失蹤者是張志新(化名)和其女友劉穎扳缕,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體别威,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡躯舔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了省古。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片粥庄。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖豺妓,靈堂內(nèi)的尸體忽然破棺而出惜互,到底是詐尸還是另有隱情,我是刑警寧澤琳拭,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布训堆,位于F島的核電站,受9級(jí)特大地震影響臀栈,放射性物質(zhì)發(fā)生泄漏蔫慧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一权薯、第九天 我趴在偏房一處隱蔽的房頂上張望姑躲。 院中可真熱鬧睡扬,春花似錦、人聲如沸黍析。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)阐枣。三九已至马靠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間蔼两,已是汗流浹背甩鳄。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留额划,地道東北人妙啃。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像俊戳,于是被迫代替她去往敵國(guó)和親揖赴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容