這一篇就應(yīng)該是繪圖這個(gè)系列的基礎(chǔ)中最后一篇了,然后,然后就過年啦?。。?!
在此之前,分享了一些關(guān)于繪圖方面的基礎(chǔ)??梢酝ㄟ^傳輸門快捷進(jìn)入:
其實(shí)堅(jiān)持更新真的對(duì)自己而言還算是蠻挑戰(zhàn)的一件事情,重點(diǎn)在于堅(jiān)持。每一次有點(diǎn)贊,和回復(fù)都讓自己感覺非常棒。知識(shí)就是用來分享的,這就是開源越來越讓人著迷的地方。
好了,來吧~Come on~
1. 繪制柱狀圖bar chart
- 獲取數(shù)組中對(duì)于每個(gè)柱狀圖的數(shù)值
- 計(jì)算柱子的寬度
- 循環(huán)計(jì)算每根柱子的高度、X/Y
- 繪制矩形
- 設(shè)置顏色
- 填充
下面模擬一個(gè)數(shù)組,繪制柱狀圖。
完成后的樣子:

柱狀圖.png
首先我們要獲取數(shù)組中常用的一些數(shù)值,有一些常見的手法:
NSArray *arry = @[@300,@232.233,@324.324,@34,@4352,@43.0];
// 找出數(shù)組中的最大數(shù)值
CGFloat maxValue = [[arry valueForKeyPath:@"@max.floatValue"] floatValue];
// 重點(diǎn)在這句話上
// @”@max.floatValue”(獲取最大值),
// @”@min.floatValue”(獲取最小值),
// @”@avg.floatValue” (獲取平均值),
// @”@count.floatValue”(獲取數(shù)組大小)
// @”@sum.floatValue”(獲取數(shù)組總和)
- (void)drawRect:(CGRect)rect{
NSArray *arry = @[@300,@232.233,@324.324,@34,@435,@43.0];
// 計(jì)算bar的寬度
CGFloat barW = self.bounds.size.width / (arry.count * 2 - 1);
// 找出數(shù)組中的最大數(shù)值
CGFloat maxValue = [[arry valueForKeyPath:@"@max.floatValue"] floatValue];
for (NSInteger i = 0; i < arry.count; i++) {
// 計(jì)算bar的高度
CGFloat barH = [arry[i] floatValue] * (self.bounds.size.height * BAR_HEIGHT_COEFFICIENT/ maxValue);
// 計(jì)算bar的XY
CGFloat barX = barW * i * 2;
CGFloat barY = self.bounds.size.height - barH;
// 繪制矩形
UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(barX, barY, barW, barH)];
// 給矩形添加隨機(jī)色
[[self randomUIColor] set];
[path fill];
}
}
- (UIColor *)randomUIColor{
UIColor *color = [UIColor colorWithRed:(arc4random_uniform(256) / 255.0) green:(arc4random_uniform(256) / 255.0) blue:(arc4random_uniform(256) / 255.0) alpha:(arc4random_uniform(256) / 255.0)];
return color;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[self setNeedsDisplay];
}
2. 繪制餅圖Pie Chart
完成后的樣子:

Paste_Image.png
- (void)drawRect:(CGRect)rect {
// Drawing code
NSArray *arry = @[@300,@232.233,@324.324,@34,@4352,@43.0];
// 計(jì)算數(shù)組中所有數(shù)值之和
CGFloat sumValue = [[arry valueForKeyPath:@"@sum.floatValue"] floatValue];
//設(shè)定圓弧的圓點(diǎn)、起始弧度
CGPoint origin = CGPointMake(150, 150);
CGFloat startAngle = 0;
CGFloat endAngle = 0;
for (NSInteger i = 0 ; i < arry.count; i++) {
// 每個(gè)數(shù)據(jù)的弧度
CGFloat angle = [arry[i] floatValue] * M_PI * 2 / sumValue;
// 計(jì)算這一段弧度的結(jié)束為止
endAngle = startAngle + angle;
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:origin radius:130 startAngle:startAngle endAngle:endAngle clockwise:YES];
// 計(jì)算下一段弧度開始的位置
startAngle = endAngle;
// 從弧邊,繪制到原點(diǎn)。用于封閉路徑,可以繪制扇形
[path addLineToPoint:origin];
// 給扇形添加隨機(jī)色
[[self randomUIColor] set];
[path fill];
}
}
- (UIColor *)randomUIColor{
UIColor *color = [UIColor colorWithRed:(arc4random_uniform(256) / 255.0) green:(arc4random_uniform(256) / 255.0) blue:(arc4random_uniform(256) / 255.0) alpha:(arc4random_uniform(256) / 255.0)];
return color;
}
//觸屏后重新渲染
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[self setNeedsDisplay];
}
3. 繪制進(jìn)度條和進(jìn)度扇形
本來也想像柱狀圖、餅狀圖一樣的寫法,但是想想其實(shí)可以做的更形象一點(diǎn)。所以打算下一篇專門寫一下如何用扇形來表達(dá)一個(gè)下載進(jìn)度。實(shí)現(xiàn)后的效果如下:

rightImage.gif
4. 神秘感增強(qiáng)器:IB_DESIGNABLE和IBInspectable
- IB_DESIGNABLE的宏的功能就是讓SB動(dòng)態(tài)渲染出該類圖形化界面;
- 使用IB_DESIGNABLE的方式,把該宏加在自定義類的前面;
這兩個(gè)配合著使用,就可以在StoryBoard上直接設(shè)置一些系統(tǒng)不提供的屬性了,例如線段的寬度、顏色等等。個(gè)性化定制一個(gè)屬于自己的SB。

Paste_Image.png
- IBInspectable 就是讓SB上出現(xiàn)屬性的修改框,可以在SB直接修改:

Paste_Image.png
5. C和OC混合繪制圖形小帖士
- C和OC繪制圖形的時(shí)候,如果混合使用,以C語言為主。

Paste_Image.png

Paste_Image.png
- context的棧操作

Paste_Image.png
哈哈,寫完這篇,下篇就開始自己繪制一個(gè)進(jìn)度條拉。不知道各位是不是已經(jīng)踏上回家的征程了吶?希望各位雞年大吉~新年新祝福,說雞不說吧~