iOS 股票K线图绘制

作者: 忍行者 | 来源:发表于2017-05-07 21:09 被阅读7177次

最近一段时间写了一个iOS的K线图。写这个纯属个人兴趣,正好提高一下自己绘图方面的能力。在写的时候,参考了Cocoa-Charts 的实现思路。 废话不多说,先上图:



特点:

  • 采用 CAShapeLayer + UIBezierPath绘制,绘制效率高,占用内存低
  • 底层视图是UIScrollView,ScrollView上面添加一个View,所有的绘制在这个View上完成。体验流畅丝滑,FPS平均在55帧以上
  • 指标支持MACD WR KDJ,指标计算采用TALib,方便扩展
  • 横竖屏切换
  • 右拉加载更多数据

代理方法

/**
 取得当前屏幕内模型数组的开始下标以及个数
 
 @param leftPostion 当前屏幕最右边的位置
 @param index 下标
 @param count 个数
 */
 - (void)displayScreenleftPostion:(CGFloat)leftPostion startIndex:(NSInteger)index count:(NSInteger)count;
/**
 长按手势获得当前k线下标以及模型
 
 @param kLineModeIndex 当前k线在可视范围数组的位置下标
 @param kLineModel   k线模型
 */
 - (void)longPressCandleViewWithIndex:(NSInteger)kLineModeIndex kLineModel:(ZYWCandleModel *)kLineModel;
/**
 返回当前屏幕最后一根k线模型
 
 @param kLineModel k线模型
 */
 - (void)displayLastModel:(ZYWCandleModel *)kLineModel;
/**
 加载更多数据
 */
 - (void)displayMoreData;`

基础属性方法

/**
 数据源数组 在调用绘制方法之前设置 。Demo中数据源个数是固定的,如需实现类似右拉加载更多效果(参考网易贵金属),需要在每次添加数据的时候设置 然后调用绘制方法 (现在本地数据是重复的6组)
 */
@property (nonatomic,strong) NSMutableArray<__kindof ZYWCandleModel*> *dataArray;

/**
 当前屏幕范围内显示的k线模型数组
 */
@property (nonatomic,strong) NSMutableArray *currentDisplayArray;

/**
 当前屏幕范围内显示的k线位置数组
 */
@property (nonatomic,strong) NSMutableArray *currentPostionArray;

/**
 可视区域显示多少根k线 (如果数据源数组不足以占满屏幕,需要手动给定宽度)
 */
@property (nonatomic,assign) NSInteger displayCount;

/**
 k线之间的距离
 */
@property (nonatomic,assign) CGFloat candleSpace;

/**
 k线的宽度 根据每页k线的根数和k线之间的距离动态计算得出
 */
@property (nonatomic,assign) CGFloat candleWidth;

/**
 k线最小高度
 */
@property (nonatomic,assign) CGFloat minHeight;

/**
 当前屏幕范围内绘制起点位置
 */
@property (nonatomic,assign) CGFloat leftPostion;

/**
 当前绘制的起始下标
 */
@property (nonatomic,assign) NSInteger currentStartIndex;

/**
 滑到最右侧的偏移量
 */
@property (nonatomic,assign) CGFloat previousOffsetX;

/**
 当前偏移量
 */
@property (nonatomic,assign) CGFloat contentOffset;

@property (nonatomic,assign) BOOL kvoEnable;

/**
 长按手势返回对应model的相对位置

 @param xPostion 手指在屏幕的位置
 @return 距离手指位置最近的model位置
 */
- (CGPoint)getLongPressModelPostionWithXPostion:(CGFloat)xPostion;

- (void)stockFill;
- (void)calcuteCandleWidth;
- (void)updateWidth;
- (void)drawKLine;

绘图基本思路

  1. 所有的绘制在UIView上面,UIView底层是一个ScrollView
  2. 设置K线之间的间距与可视区域想要显示的K线个数,动态计算出K线的宽度。之所以没有直接设置K线宽度,是为了保证每次滑动的时候,屏幕内总是占满整数倍的K线个数。
  3. 通过k线的个数,计算出当前View的与它的父视图ScrollView的宽度
  4. KVO监听ScrollView的contentOffset属性,计算每次滑动将要显示的K线数组(currentDisplayArray)
  5. 计算currentDisplayArray的最大值与最小值,然后得出每一根K线对应屏幕的坐标,绘图

链接

[ZYWStock]https://github.com/zyw113/ZYWStock.git

  • 在使用过程中如果遇到什么问题,欢迎给我简书留言,或者直接Pull request,欢迎star or fork。
  • 更多功能,敬请期待~~~

相关文章

  • iOS股票K线图

    mark:iOS股票K线图 iOS 股票K线图绘制 iOS 股票K线图绘制 从零开始实现k线图走势图绘制(iOS实战篇)

  • iOS股票K线图绘制

    写在开头 最近造了个轮子,绘制股票的k线图。刚开始接收到这个需求的时候真的一脸懵逼,因为没有接触过相关知识。 不过...

  • iOS 股票K线图绘制

    最近一段时间写了一个iOS的K线图。写这个纯属个人兴趣,正好提高一下自己绘图方面的能力。在写的时候,参考了Coco...

  • ios股票K线图的绘制

    前言:因为工作需要,要绘制一个股票K线图,因为自己不炒股,所以对股票知识很是有限,当时也想在网上找个demo直接拿...

  • MPAndroidChart绘制K线图(三)

    MPAndroidChart绘制K线图(一)高亮线自定义MPAndroidChart绘制K线图(二)动态时间格式+...

  • MPAndroidChart绘制K线图(二)

    MPAndroidChart绘制K线图(一)高亮线自定义MPAndroidChart绘制K线图(二)动态时间格式+...

  • 什么是K线

    K线图表是市场运行轨迹的直接描述,无论是股票、外汇、黄金、期货,所有的证券k线图表只要其绘制的原理和机制相同,必然...

  • iOS股票K线图

    有段时间没更新文章了,之前放出了分时图Demo StockChart,应广大网友的呼声,现在放出K线图Demo,代...

  • iOS 股票K线图

    好久没有在简书写东西记录, 前段时间想要将现在工程中用的股票图表绘制重写一遍, 主观臆断一两个星期可以完成, 最后...

  • iOS股票K线图、分时图绘制

    标准对标雪球APPK线。 Z君这几天会将之前写的K线框架review,同时在简书也会将之前搭建K线遇到的问题,发出...

网友评论

  • 汪斗斗:FPS在左右滑动的时候有点过低了:smile:
    ps:在模拟器上运行了一下
  • 9e5f2143c765:双指捏合放大的时候,怎么是前面的放大,不是当前选中的地方放大?
    忍行者:捏合手势已经改了,最近优化了这里
  • 安心啊啊678:哥,没明白ZYWCandleChartView.m中
    - (void)stockFill
    {
    [self initConfig];
    [self initLayer];
    [self.superScrollView layoutIfNeeded];//?
    [self calcuteCandleWidth];
    [self updateWidth];
    [self drawKLine];
    }
    这句代码什么用意,望开导一下
    还有设置完scrollView的contentOffset 也就是这句:
    self.superScrollView.contentOffset = CGPointMake(klineWidth - prevContentOffset,0);
    [self layoutIfNeeded];//?
    是啥作用
  • 苦笑男神:您好,在处理 Y轴的动态变化,是如何做的呢?
    是不是: 滑动时,根据屏幕里的点,找出最大和最小值,动态改变Y轴刻度,再重新绘制?
    忍行者:@苦笑男神 嗯 是这样处理的
  • 圣僧留步:我觉得写的还不错,但是有个问题,就是不可能所有的人跟你的需求样式都是一样的,有时候我们只需要你的K线图的一部分,还有,如果你的东西集成进项目方便的话,我相信会有更多人使用
  • qjsxq:您好,我把TAlib拖入项目中还没用,编译就报错,怎么破
    qjsxq:@忍行者 嗯嗯,已经解决了,是在pch文件中 将所有文件放入#ifdef __OBJC__ #endif
    忍行者: #ifdef __OBJC__ #endif 加上这个
  • WheatDen:想问下,如果想让K线图根据最新价格跳动起来,怎么实现?
    忍行者:@青卷三部 刷新只是在当前屏幕内刷新,无非是数据源变多了。计算当前屏幕范围内的数据,再次重绘不会有太大的消耗的。
    WheatDen:@忍行者 有一个问题,如果我刷新所有的数据,这样就会太耗内存,如果只刷新屏幕上显示的数据,那怎样才能确定我显示的那一屏数据,就是K线图的最后一屏的数据?因为让K线图根据最新价格跳动起来,也就是让最后一个点跳动。
    忍行者:每次数据有变化的时候,刷新数据就行了。
  • Alexander:老铁: 导入TALib报了好多错, 咋回事啊?
    忍行者:#ifdef __OBJC__ #endif 加上这个,试试
  • 怪客半:这两天在学习检测内存泄露,拿你的项目跑了下。。。可以改进改进
  • PGOne爱吃饺子:这种UI,我看的都有点乱,楼主厉害了
    PGOne爱吃饺子:嗯嗯 好的
    忍行者:有啥问题,一起交流哈:smile:
  • hexiaoxiao:之前做过画板应用.虽然CAShapeLayer占用内存比较少, 但是大量的CAShapeLayer,还有需要管理这些layer布局也是有很大消耗.直接用单个view,根据每个对象的布局颜色, 然后使用setNeedsDisplayInRect绘制 会更流畅.
    CAShapeLayer还是比较适合线条颜色一样的这种绘制.
    忍行者:@我帮你打水 一个是在制定区域重绘,一个是整个区域重绘,指定区域重绘可以减少很多不必要的开销。
    AppleIdGX:但是K线图要滑动的时候,重绘的rect不就是整个显示区域么?所以setNeedsDisplayInRect跟drawRect的性能消耗也没太大区别?
    忍行者:是的 :smile: setNeedsDisplayInRect确实可以减少不必要的一些绘制。
  • MathiasLuo:作者良心
    忍行者:@MathiasLuo 这位朋友有点熟悉,wuxia。:grin:
  • flan89:想问下K线的用的是真实的大盘数据嘛?
    flan89:@忍行者 恩了解,主要就是想问下有没有真实免费的数据源用:smile:
    忍行者:@flan89 代码中的数据,是本地的模拟数据。想要什么数据,直接替换成你自己的就可以了。只要数据模型保持一致就行了。
  • 欢欢1206:太乱了,封装下会更好
    欢欢1206:@忍行者 还有个地方就是 K线图滑动,快要停下来的时候有卡顿现象
    忍行者:@欢欢1206 谢谢你提的建议,这个项目我会持续进行改进、优化。:smile::smile::smile:

本文标题:iOS 股票K线图绘制

本文链接:https://www.haomeiwen.com/subject/akdptxtx.html