k线图流畅 如何ios_ios k线图 - CSDN
  • iOS 股票K线图、分时图,基本上翻遍了开源的项目,要不就是只分享了分时图没有k线纯粹一个噱头,要不就是有K线的性能叫人捉急,干脆自己写一套,分享出来。 前言:观察了市面上排名前十的金融类APP,唯雪球的K线交互...

    前言:以下是博主2016年在做iOS研发时,在某书上发的,搬到CSDN上来,后续会将当时构建的思考逻辑发上来。

    iOS 股票K线图、分时图,基本上翻遍了开源的项目,要不就是只分享了分时图没有k线纯粹一个噱头,要不就是有K线的性能叫人捉急,干脆自己写一套,分享出来。

    前言:观察了市面上排名前十的金融类APP,唯雪球的K线交互足够流畅,故效仿雪球实现K线搭建。分时图过于简单,没有太多差别。采用CAShapeLayer和UIBezierPath绘制。
    这里写图片描述
    源码已在 Github 上开源,有需要的,拿走不谢,记得给个小星星。源码地址:https://github.com/cclion/CCLKLineChartView

    展开全文
  • 这是以雪球APP为原型,基于iOSK线开源项目。 该项目整体设计思路已经经过某成熟证券APP的商业认证。 本项目将K线业务代码尽可能缩减,保留核心功能,可流畅、高效实现手势交互。 K线难点在于手势交互和数据动态...

    介绍:

    • 这是以雪球APP为原型,基于 iOS的K线开源项目。
    • 该项目整体设计思路已经经过某成熟证券APP的商业认证。
    • 本项目将K线业务代码尽可能缩减保留核心功能,可流畅、高效实现手势交互。
    • K线难点在于手势交互和数据动态刷新上,功能并不复杂,关键在于设计思路。

    演示:

    K线演示文档.gif

    建议:

    • 如果搭建K线为公司业务,不建议采用集成度高的开源代码。庞大臃肿,纵然短期匆忙上线,难以应付后期灵活需求变更。

    Objective-C版请移步 https://github.com/cclion/CCLKLineChartView
    Swift版请移步 https://github.com/cclion/KLineView 。

    设计思路&&难点:

    K线难点在于手势的处理上,捏合、长按、拖拽都需要展示不同效果。以下是Z君当时做K线时遇到的问题的解决方案;

    1. 捏合手势需要动态改变K线柱的宽度,对应的增加或减少当前界面K线柱的展示数量,并且根据当前展示的数据计算出当前展示数据的极值。

    采用UITableView类实现,将K线柱封装在cell中,在tableview中监听捏合手势,对应改变cell的高度,同时刷新cell中K线柱的布局来实现动态改变K线柱的宽度。

    采用UITableView还有一个好处就是可以采用cell的重用机制降低内存。

    注意:因为UITableView默认是上下滑动,而K线柱是左右滑动,Z君这里将UITableView做了一个顺时针90°的旋转。

    tableView旋转90°

     

    2. K线柱绘制

    K线柱采用CAShapeLayer配合UIBezierPath绘制,内存低,效率高,棒棒哒!

    关于CAShapeLayer的使用大家可以看这篇https://zsisme.gitbooks.io/ios-/content/chapter6/cashapelayer.html
    (现在的google、baidu,好文章都搜不到,一搜全是简单调用两个方法就发的博客,还是翻了两年前的收藏才找到这个网站,强烈推荐大家)

    3. 捏合时保证捏合中心点不变,两边以捏合中间点为中心进行收缩或扩散

    因为UITableView在改变cell的高度时,默认时不会改变偏移量,所以不能保证捏合的中心点不变,这里我们的小学知识就会用上了。

    捏合时状态.png

     

    我们可以通过变量定义控件间距离。

     

    捏合前后.png

    保证捏合中心点的中K线柱的中心点还在捏合前,就需要c1 = c2 ,计算出O2,在捏合完,设置偏移量为O2即可。

    计算偏移量.png

     

    4. K线其他线性指标如何绘制

    在K线中除了K线柱之外,还有其他均线指标,连贯整个数据显示区。

    线性指标

     

    由图可以看出均线指标由每个cell中心点的数据连接相邻的cell中心点的数据。我们依旧将绘制放在cell中,将相连两个cell的线分割成两段,分别在各自所属的cell中绘制。

    需要我们做的就是就是在cell中传入相邻的cellsoureData,计算出相邻中点的位置,分为两段绘制。

    分割绘制

     


    大家针对K线有什么问题都可以在下面留言,会第一时间解答。
    未完待续

    展开全文
  • iOS 绘制股票K线图

    2017-09-03 23:38:52
     k线图:有最新价、收盘价、开盘价、最高价、最低价、均价、卖量、买量等等。而我们需要展示给用户看的第一眼就是把它们全部绘制为k线图,直观。还有部分要转化为数值直接推动;  蜡烛:需要用到收盘价、开盘价...

    //联系人:石虎  QQ: 1224614774昵称:嗡嘛呢叭咪哄

    一、k线图概念

         k线图:有最新价、收盘价、开盘价、最高价、最低价、均价、卖量、买量等等。而我们需要展示给用户看的第一眼就是把它们全部绘制为k线图,直观。还有部分要转化为数值直接推动;

         蜡烛需要用到收盘价、开盘价、最高价、最低价;红色是涨(国内),开盘价在上,收盘价在下;绿色是相反的;

    效果图:


    二、CAShapeLaye优点

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


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

    谢谢!!!

    展开全文
  • iOS 股票K线图绘制

    2017-07-10 22:29:18
    最近一段时间写了一个iOSK线图。写这个纯属个人兴趣,正好提高一下自己绘图方面的能力。在写的时候,参考了Cocoa-Charts 的实现思路。 废话不多说,先上图: 特点: 采用 CAShapeLayer +...

    本文来自简书,原文地址:http://www.jianshu.com/p/f7906f5b4f4c

    最近一段时间写了一个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。
    • 更多功能,敬请期待~~~
    展开全文
  • k线系列目录 查看目录请点击这儿 在分时线写完以后,我们开始接着学习如何写K线。其实k线并没有想象的那么复杂,还是像前几篇文章提供的思路一样,第一步、第二步、第三步…….把一个复杂的问题简单化,才是我们最...

    k线系列目录

    查看目录请点击这儿


    在分时线写完以后,我们开始接着学习如何写K线。其实k线并没有想象的那么复杂,还是像前几篇文章提供的思路一样,第一步、第二步、第三步…….把一个复杂的问题简单化,才是我们最需要做的事情。

    首先看一下最终要完成的效果图:

    K线

    不管是现货还是股票类的k线,都是一样的。因为k线本质上是用来表示某个商品价格变动的情况(如果不了解k线基础知识,点击这儿)。上图的k线是由一根根蜡烛组成,分为主图、副图、主图指标、副图指标四部分,其中主图中还包含日期部分。

    滑动的选择

    Tip:如果读这一小节的内容感觉到云里雾里时,千万不要着急,其实完全可以略过这小节内容,跟着文章的思路往下走,等做完这部分内容时,可以再回顾一下。

    在绘制之前,我们来讨论一个重要的问题,也是这篇文章说的一个重点,就是关于滑动的选择。

    经过使用Reveal对市面上多个app的查看,以及自己在开发中踩了好多坑,在这里提供两种方式:

    1. 单个View
    2. 单个View + ScrollView

    第一种指的是在主副图View上添加滑动手势,然后根据坐标产生的位移来实时刷新主副图View上的蜡烛。

    第二种指的是在主副图View上方盖一个ScrollView,然后用户滑动ScrollView,根据ScrollView产生的偏移量来实时刷新主副图View上的蜡烛。

    当选用第一种方式时,因为是添加滑动手势来获取的偏移量,所以这个偏移量不是非常线性,给用户的感觉是滑动起来不顺畅。解决办法是获取偏移量时,需要多次调试,每次获取的偏移量需要判断范围以及增加合适的倍数,尽量能保证View获得的偏移量线性。但使用这种方式的好处是不增加其他控件,在视图层次上很清晰。

    当选用第二种方式时,用户能感知到的滑动体验很好,会感觉非常流畅。但有一个缺点不容忽视,那就是ScrollView的ContentSize是随着加载的蜡烛数量的增加而变大的,因为只有ContentSize和蜡烛数量相对应时,才可以滑动到最左或最右。所以,当一次性加载的蜡烛数量过高,会导致一个巨大的ScrollView存在。

    边框的绘制

    当明确了我们要达到的效果后,我们也可以仿照效果图把k线分为4部分:主图指标、主图、副图指标、副图。这里默认k线4部分是在同一个View上,并且是在这个view上面添加滑动手势。

    绘制线段的方法在画分时线的文章中就已经讲过,这里不再重复。直接上代码:

    //设置主图、主图指标、副图、副图指标rect
        _mainIndexRect = CGRectMake(0, 0, CGRectGetWidth(self.frame), mainIndexH);
        _mainRect = CGRectMake(0, mainIndexH, CGRectGetWidth(self.frame), (CGRectGetHeight(self.frame) - (mainIndexH + accessoryIndexH + dateH)) * mainFrameScale);
        _accessoryIndexRect = CGRectMake(0, mainIndexH + CGRectGetHeight(_mainRect)+dateH, CGRectGetWidth(self.frame), accessoryIndexH);
        _accessoryRect = CGRectMake(0, mainIndexH + CGRectGetHeight(_mainRect)+dateH+accessoryIndexH, CGRectGetWidth(self.frame), (CGRectGetHeight(self.frame) - (mainIndexH + accessoryIndexH + dateH)) * (1-mainFrameScale));
    
    
        CAShapeLayer *borderLayer = [CAShapeLayer layer];
        UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.bounds];
    
        [path moveToPoint:CGPointMake(0, mainIndexH)];
        [path addLineToPoint:CGPointMake(CGRectGetWidth(self.frame), mainIndexH)];
    
        [path moveToPoint:CGPointMake(0, CGRectGetMaxY(_mainRect))];
        [path addLineToPoint:CGPointMake(CGRectGetWidth(self.frame), CGRectGetMaxY(_mainRect))];
    
        [path moveToPoint:CGPointMake(0, CGRectGetMinY(_accessoryIndexRect))];
        [path addLineToPoint:CGPointMake(CGRectGetWidth(self.frame), CGRectGetMinY(_accessoryIndexRect))];
    
        [path moveToPoint:CGPointMake(0, CGRectGetMinY(_accessoryRect))];
        [path addLineToPoint:CGPointMake(CGRectGetWidth(self.frame), CGRectGetMinY(_accessoryRect))];
    
        float mainUnitH = CGRectGetHeight(_mainRect) / 4.f;
        float mainUnitW = CGRectGetWidth(_mainRect) / 4.f;
    
        for (int idx = 1; idx <= 3; idx++)
        {
            //画3条横线
            [path moveToPoint:CGPointMake(0, mainIndexH + mainUnitH * idx)];
            [path addLineToPoint:CGPointMake(CGRectGetWidth(self.frame), mainIndexH + mainUnitH * idx)];
    
            //画3条竖线
            [path moveToPoint:CGPointMake(idx * mainUnitW, mainIndexH)];
            [path addLineToPoint:CGPointMake(idx * mainUnitW, CGRectGetMaxY(_mainRect))];
    
            //画3条竖线
            [path moveToPoint:CGPointMake(idx * mainUnitW, CGRectGetMinY(_accessoryRect))];
            [path addLineToPoint:CGPointMake(idx * mainUnitW, CGRectGetMaxY(_accessoryRect))];
        }
    
        float accessoryUnitH = CGRectGetHeight(_accessoryRect) / 2.f;
        [path moveToPoint:CGPointMake(0, CGRectGetMaxY(_accessoryRect) - accessoryUnitH)];
        [path addLineToPoint:CGPointMake(CGRectGetWidth(self.frame), CGRectGetMaxY(_accessoryRect) - accessoryUnitH)];
    
        borderLayer.path = path.CGPath;
        borderLayer.lineWidth = 0.5f;
        borderLayer.strokeColor = [UIColor blackColor].CGColor;
        borderLayer.fillColor = [UIColor clearColor].CGColor;
    
        [self.layer addSublayer:borderLayer];

    代码执行效果如下:

    k线边框

    需要源码的话,点这里

    展开全文
  • HSStockChart 是一个绘制股票分时K 线图的库。支持流畅的回弹拖动,长按十字线,捏合放大缩小等功能,主要使用了 CAShapeLayer 来绘图,相比使用 Core Graphics 和重写 drawRect 的方法更高效,占用内存更小。 ...
  • (CAShapelayer UIBezierPath)绘制K线支撑横竖屏切换、刷新、长按、缩放、masonry适配,完美支持金融产品 非常的流畅,占用内存少,使用矢量进行填充K线 由于项目比较大,下载请移步GitHub:...
  • 折线,支持放大缩小,横向定位放大,增加长按功能,y轴的值可以自己设置。采用贝塞尔曲线,核心绘图,支持大数据量。减少卡顿,左右滑动流畅 GitHub地址https://github.com/Zws-China/WSLineChartView 将...
  • (CAShapelayer UIBezierPath)绘制K线支撑横竖屏切换、刷新、长按、缩放、masonry适配,完美支持金融产品 非常的流畅,占用内存少,使用矢量进行填充K线 重新封装绘制线方法、显示隐藏副图、刷新时间问题解决、十字...
  • Swift 专业版K线 TableView无数据时使用占位控件显示cell iOS 小动画 iOS 高仿微信扫一扫 iOS非常灵活的HUD(XNProgressHUD) ios之高仿QQ侧滑控件 -- OC/Swift4.0 支持单任务下载和批量...
  • 具备多种图表类型—柱状 、区域图、线性图、扇形图、圆环图、气泡图、K线图、散点图、雷达图、漏斗图热图等等几十种图表,并且同时支持3D展示,出色的灯光效果和流畅的动画让你的数据看起来更加华丽。并且最令人心动...
  • 现在公司有一个要求:连接蓝牙BLE4.0之后,获取传递过来的数据,然后以点的形式连接成线。 我采用的是CAShapeLayer和UIBezierPath绘制曲线,当一开始点比较少的时候,可以非常流畅的把线画出来 但是当点的数目达到...
  • Swift版本点击这里欢迎加入交QQ流群: 594119878github排名 https://github.com/trending,github搜索:https://github.com/search使用方法:根据目录关键字搜索,记得包含@,以保证搜索目录关键字的唯一性。...
  • ,iosUI组件介绍,iOS开发常用工具整理,ios开发总结 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SDWebImage多个缩略缓存组件 UICKeyChainStore存放用户账号密码组件 ...
  • iOS资源大全中文版

    2017-07-10 22:32:17
    iOS资源大全中文版 转载 :https://github.com/phlls/awesome-ios-cn 我想很多程序员应该记得 GitHub 上有一个 Awesome - XXX 系列的资源整理。awesome-ios 就是 vsouza 发起维护的 iOS 资源列表,内容包括:...
  • iOS 常用第三方库

    2018-06-04 15:38:52
    转载自:https ://github.com/Tim9Liu9/TimLiu-iOS目录UI下拉刷新模糊效果自动版式富文本图表表相关与的TabBar隐藏与显示HUD与吐司对话框其他UI动画侧滑与右滑返回手势GIF动画其他动画网络相关网络连接图像获取网络...
1 2 3 4 5 ... 20
收藏数 1,312
精华内容 524
关键字:

k线图流畅 如何ios