iOS绘制3D饼图的实现方法

2025-05-29 0 63

实现核心

1.压缩饼图,使饼图3D的效果,并不是真正的画了个3D圆柱

2.绘制厚度,带阴影效果,让看上去像是圆柱的高

3.路径添加好了,用颜色填充后绘制一下,添加阴影后还需绘制一遍

饼图添加阴影的思考

之前这加阴影的一段不是很明白,为啥设颜色和阴影都要draw一次

进过反复的测试,我自己分析了一下,每次draw一下想当于,把当前的设置画出来,再次draw就在这基础上,再画最近的设置,这里加颜色和阴影就像是一层一层的画上去。要是不draw的话,再设置颜色相当于重新设置了颜色,之前设置的颜色就无效了。同时要结合path使用,如果设置一场颜色draw一次,再设置颜色draw一次,后面设置的颜色是无用的。需要添加阴影的部分,需要用path路径绘制。

效果图

iOS绘制3D饼图的实现方法

3D饼图的核心代码如下:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97
#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:

?

1

2

3

4

5

6

7

8

9

10

11

12
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开发者们能有一定的帮助,如果有疑问大家可以留言交流。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 iOS绘制3D饼图的实现方法 https://www.kuaiidc.com/91567.html

相关文章

发表评论
暂无评论