前言:因為工作需要,要繪制一個股票K線圖,因為自己不炒股,所以對股票知識很是有限,當時也想在網上找個demo直接拿來用的,但是找了很多都不合適,后來查了些資料,也看了很多別人的demo,打算自己寫,此文針對不會畫直線畫文字的新手, 沒有考慮優化問題! 大神請略過 !
因為自己當時對股票知識很是有限, 所以這里就從最基礎說起, 首先看一下K線圖解, 了解一下一個K線點所需要的數據:
陽線代表股票上漲(收盤價大于開盤價), 陰線則代表股票下跌(收盤價小于開盤價), 由此可以看出畫一個K線點需要四個數據, 分別是: 開盤價 - 收盤價 - 最高價 - 最低價, 根據這四個數據畫出上影線實體以及下影線, 柱狀圖(成交量)先不考慮, K線圖畫出來之后, 成交量柱狀圖就不在話下了;
這里主要說一下怎么繪制線段和實體以及字符串,這些如果會了,那么繪制K線圖就不是問題了;
創建一個繼承自UIView的類YBStockChartView, 就在這個類里邊進行繪制, 首先要繪制背景, 無非就是那些橫線豎線虛線之類的, 下邊是畫一條從p1
到p2
的實線線段的代碼:
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
// 設置背景填充顏色
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
CGContextFillRect (context, self.bounds); // 填充范圍
// 畫線段
CGPoint p1 = CGPointMake(20, 20);
CGPoint p2 = CGPointMake(rect.size.width - 20, rect.size.height - 20);
CGContextSetLineWidth(context, 1.0f);
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextMoveToPoint(context, p1.x, p1.y);
CGContextAddLineToPoint(context, p2.x, p2.y);
CGContextStrokePath(context);
}
如果要畫虛線加上這句CGFloat dash[] = {1,3};CGContextSetLineDash(context, 0, dash, 0);
代碼即可,關于虛線,感興趣的可以上網搜一下更加詳細說明,這里只簡單說一下{1,3}代表畫一個點,空三個點,在畫一個點在空三個點這樣循環畫出來的一條虛線;
會畫線段之后,K線圖背景就可以這樣輕輕松松的畫出來了,那么接下來開始繪制K線點,K線點常見的有兩種, 一種是空心的一種是實心的,我們先來畫一個空心的,空心的分解一下就是兩條線段加上一個矩形邊框,只需要四個點就可以畫出來,如下圖:
下邊是實現代碼:
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
CGPoint p1 = CGPointMake(100, 30);
CGPoint p2 = CGPointMake(100, 70);
CGPoint p3 = CGPointMake(100, 120);
CGPoint p4 = CGPointMake(100, 170);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextSetLineWidth(context, 2.0);
// p1 -> p2線段
CGContextMoveToPoint(context, p1.x, p1.y);
CGContextAddLineToPoint(context, p2.x, p2.y);
// p3 -> p4線段
CGContextMoveToPoint(context, p3.x, p3.y);
CGContextAddLineToPoint(context, p4.x, p4.y);
CGContextStrokePath(context);
// 中間實體邊框
CGContextStrokeRect(context, CGRectMake(100 - 14 / 2.0, p2.y, 14, p3.y - p2.y));
}
下邊開始畫實心的,實心的比空心的簡單,可以先畫一條線段直接從p1畫到p4,然后在中間在畫實體就好了下邊是效果圖:
實現代碼:
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
CGPoint p1 = CGPointMake(185, 30);
CGPoint p2 = CGPointMake(185, 70);
CGPoint p3 = CGPointMake(185, 120);
CGPoint p4 = CGPointMake(185, 170);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
CGContextSetLineWidth(context, 2.0);
// p1 -> p4
CGContextMoveToPoint(context, p1.x, p1.y);
CGContextAddLineToPoint(context, p4.x, p4.y);
CGContextStrokePath(context);
// 畫實心實體
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextFillRect(context, CGRectMake(p1.x - 14 / 2.0, p2.y, 14, p3.y - p2.y));
}
然后將畫K線的代碼封裝成一個方法,然后將最高價最低價開盤價收盤價等轉換成坐標,通過傳入四個參數就可以將K線點畫出來,然后循環調用該方法就好,至于均線就是一個點一個點連接起來的,同樣可以通過線段畫出來,這里就不多說了,還有一個十字線,這個只要會畫線段就會畫十字線,這個也不多說了;
之前看到別人的demo K線圖可以左右滑動以及放大縮小,本來還以為是像ScrollView那樣的,后來發現并不是這樣,而是當手指滑動或者嚙合的時候調用了- (void)drawRect:(CGRect)rect
方法,而是又重新畫上去了,因為調用比較頻繁,所以看起來像是在滑動一樣!在這里需要一個變量來控制繪制顯示在視圖上的第一個點,然后在通過K線點寬度以及K線點之間的間隔計算出該視圖上能繪制會少個K線點,當手勢滑動或者嚙合的時候通過控制這個變量來控制要繪制的第一個點!這點復雜,但是不難,就不多說了!
還需要一個變量來記錄當前手指滑動所選擇的K線點,然后在手指滑動的時候通過代理方法或者block將該點所對應的模型傳過去,這樣在外部就可以獲取到當前用戶所點擊或者選擇模型對應的數據,在外部就可以進行其他操作;
接下來就是畫文字,顯示日期時間對應的價格日期等信息,畫文字或者說畫字符串更合理一點,用的是屬性字符串NSMutableAttributedString
廢話不多說,上代碼:
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
NSString *str = @"我是要繪制的字符串";
NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:str];
// 設置字符串字體大小以及顏色
[attributedStr setAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:20], NSForegroundColorAttributeName:[UIColor greenColor]} range:NSMakeRange(0, str.length)];
// 要繪制的區域
CGRect strRect = CGRectMake(50, 80, attributedStr.size.width, attributedStr.size.height);
// 給字符串添加一個弧形背景
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:strRect cornerRadius:attributedStr.size.height / 2.0];
CGContextAddPath(context, path.CGPath);
CGContextDrawPath(context, kCGPathEOFill);
// 繪制
[attributedStr drawInRect:strRect];
}
效果圖:
這些掌握了之后就可以繪制專屬自己的K線圖了,其他的都是一些細節小問題,CGContextRef還有很多用法,有興趣的自己可以找度娘,接下來附上我的最終的繪制結果:
另外這個demo我已經封裝好了,可以直接拿去使用,本來是想連那些指標什么的都繪制好的,因為自己對股票知識不了解,在加上公司把這部分功能給砍了,所有demo里邊就沒有繪制各項指標;
如果對你幫助就給個star吧!