国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > iOS > 正文

iOS繪制3D餅圖的實現方法

2020-07-26 02:59:33
字體:
來源:轉載
供稿:網友

實現核心

     1.壓縮餅圖,使餅圖有3D的效果,并不是真正的畫了個3D圓柱

     2.繪制厚度,帶陰影效果,讓看上去像是圓柱的高

     3.路徑添加好了,用顏色填充后繪制一下,添加陰影后還需繪制一遍

餅圖添加陰影的思考

之前這加陰影的一段不是很明白,為啥設顏色和陰影都要draw一次

進過反復的測試,我自己分析了一下,每次draw一下想當于,把當前的設置畫出來,再次draw就在這基礎上,再畫最近的設置,這里加顏色和陰影就像是一層一層的畫上去。要是不draw的話,再設置顏色相當于重新設置了顏色,之前設置的顏色就無效了。同時要結合path使用,如果設置一場顏色draw一次,再設置顏色draw一次,后面設置的顏色是無用的。需要添加陰影的部分,需要用path路徑繪制。

效果圖

3D餅圖的核心代碼如下:

#import "SSSolidCakeView.h"@implementation SSSolidCakeView#pragma mark 重寫繪制方法- (void)drawRect:(CGRect)rect{  //第一步獲得上下文  CGContextRef cakeContextRef = UIGraphicsGetCurrentContext();  //反鋸齒,讓圖形邊緣更加柔和(Sets whether or not to allow anti-aliasing for a graphics context.)  CGContextSetAllowsAntialiasing(cakeContextRef, TRUE);  //縮放坐標系的比例,通過設置y軸壓縮,然后畫代陰影的厚度,就畫出了像是3D餅圖的效果  CGContextScaleCTM(cakeContextRef, _xScale, _yScale);  //餅圖最先的起始角度  CGFloat startAngle =0;  for (int i = 0; i<_dataArray.count; i++) {    //畫餅的橫截面,上一部分完整的圓    //cake當前的角度    CGFloat currentAngle = [_dataArray[i] floatValue];    //結束的角度    CGFloat endAngle = startAngle + currentAngle;    //每一塊cake的起點,也就是圓心    CGContextMoveToPoint(cakeContextRef, _cakeCenter.x, _cakeCenter.y);    //添加對應角度扇形    CGContextAddArc(cakeContextRef, _cakeCenter.x, _cakeCenter.y, _cakeRadius, startAngle*M_PI*2, endAngle*M_PI*2, 0);    //得到對應的顏色    UIColor *currentColor = _colorArray[i];    //設置邊界顏色    CGContextSetStrokeColorWithColor(cakeContextRef, currentColor.CGColor);    //設置填充顏色    CGContextSetFillColorWithColor(cakeContextRef, currentColor.CGColor);    //畫子路徑,這里就繪制還不是在畫完厚度再繪制,是因為并不需要繪制所有cake的厚度,但是上一部分的圓是都要繪制的    CGContextDrawPath(cakeContextRef, kCGPathFill);    //餅圖上一部分圓,startAngle處的起點坐標    CGFloat upStartX = _cakeCenter.x+_cakeRadius*cos(startAngle*2*M_PI);    CGFloat upStartY = _cakeCenter.y+_cakeRadius*sin(startAngle*2*M_PI);    //餅圖上一部分圓,endAngle處的終點坐標    CGFloat upEndX = _cakeCenter.x+_cakeRadius*cos(endAngle*2*M_PI);    CGFloat upEndY = _cakeCenter.y+_cakeRadius*sin(endAngle*2*M_PI);    //餅圖厚度在角度結束處y坐標    CGFloat downEndY = upEndY + _cakeHeight;    //畫圓柱的側面,餅圖的厚度,圓柱的前半部分能看到,后半部分是看不到    //開始的角度如果>=M_PI,就會在圓柱的后面,側面厚度就沒必要畫了    if (startAngle<0.5) {      //繪制厚度      CGMutablePathRef path = CGPathCreateMutable();      CGPathMoveToPoint(path, nil, upStartX, upStartY);      //當結束的角度>0.5*2*M_PI時,結束的角度該是M_PI的地方(視覺原因)      if (endAngle>0.5) {        //上部分的弧        CGPathAddArc(path, nil, _cakeCenter.x, _cakeCenter.y, _cakeRadius, startAngle*2*M_PI, M_PI, 0);        //在角度結束的地方,上部分到下部分的直線        CGPathAddLineToPoint(path, nil, _cakeCenter.x-_cakeRadius, _cakeCenter.y+_cakeHeight);        //下部分的弧        CGPathAddArc(path, nil, _cakeCenter.x, _cakeCenter.y + _cakeHeight, _cakeRadius, M_PI, startAngle*2*M_PI, 1);        //在角度開始的地方,從下部分到上部分的直線        CGPathAddLineToPoint(path, nil, upStartX, upStartY);      }      else{        //上部分的弧        CGPathAddArc(path, nil, _cakeCenter.x, _cakeCenter.y, _cakeRadius, startAngle*2*M_PI, endAngle*2*M_PI, 0);        //在角度結束的地方,上部分到下部分的直線        CGPathAddLineToPoint(path, nil, upEndX, downEndY);        //下部分的弧        CGPathAddArc(path, nil, _cakeCenter.x, _cakeCenter.y + _cakeHeight, _cakeRadius, endAngle*2*M_PI, startAngle*2*M_PI, 1);        //在角度開始的地方,從下部分到上部分的直線        CGPathAddLineToPoint(path, nil, upStartX, upStartY);      }      //之前這一段不是很明白,為啥設顏色和陰影都要draw一次      //我自己嘗試并理解分析了一下,每次draw一下想當于,把當前的設置畫出來,再次draw就在這基礎上,再畫當前的設置,這里加顏色和陰影就是一層一層的畫上去。要是不draw的話,再設置顏色相當于重新設置了顏色,之前設置的顏色就無效了。      CGContextAddPath(cakeContextRef, path);      CGContextDrawPath(cakeContextRef, kCGPathFill);      //加陰影      [[UIColor colorWithWhite:0.2 alpha:0.4] setFill];      CGContextAddPath(cakeContextRef, path);      CGContextDrawPath(cakeContextRef, kCGPathFill);    }    //最后一句,上一塊的結束角度是下一塊的開始角度    startAngle = endAngle;  }  //此時不能用以下的方法填充,會導致餅圖就一種顏色  //CGContextFillPath(contextRef);}-(void)setDataArray:(NSArray *)dataArray{  _dataArray = dataArray;  //重新繪制  [self setNeedsDisplay];}

這里要說明一下,我的數組是百分比數組,由數值轉化為百分比的過程我沒有在這里處理。

如何使用view:

  self.solidCakeView = [[SSSolidCakeView alloc]init];  self.solidCakeView.dataArray = _dataArray;  self.solidCakeView.colorArray = _colorArray;  self.solidCakeView.nameArray = _nameArray;  self.solidCakeView.cakeCenter = CGPointMake(200, 200);  self.solidCakeView.cakeRadius = 100;  self.solidCakeView.cakeHeight = 30;  self.solidCakeView.xScale = 1;  self.solidCakeView.yScale = 0.8;  self.solidCakeView.backgroundColor = [UIColor whiteColor];  self.solidCakeView.frame = CGRectMake(0, 0, PhoneScreen_WIDTH-100, PhoneScreen_HEIGHT-20);  [self.view addSubview:self.solidCakeView];

3D餅圖如何繪制及使用已經用代碼介紹完了,相信看到這大家應該也能實現3D餅圖了。

本文參考了:http://blog.csdn.net/donny_zhang/article/details/9145379  感謝博主!

總結

以上就是這篇文章的全部內容了,希望本文的內容對各位iOS開發者們能有一定的幫助,如果有疑問大家可以留言交流。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 堆龙德庆县| 衡南县| 黄骅市| 宜兰市| 定州市| 新竹市| 高陵县| 赣榆县| 华蓥市| 陇西县| 淳安县| 毕节市| 富阳市| 徐汇区| 集贤县| 大英县| 上蔡县| 文成县| 酉阳| 伽师县| 伽师县| 无锡市| 寿阳县| 瑞丽市| 宿州市| 资阳市| 寻乌县| 云龙县| 叶城县| 桃园市| 巴林右旗| 惠水县| 洛南县| 安平县| 临安市| 洮南市| 尖扎县| 宾川县| 扎鲁特旗| 尉犁县| 南靖县|