zoukankan      html  css  js  c++  java
  • iOS简易柱状图(带动画)--新手入门篇

    叨逼叨

    好久没更新博客了,才几个月,发生了好多事情,处理了好多事情。不变的是写代码依然在继续。

    做点啥子

    看看objective-c的书,学着写了个柱状图,只是练习的demo而已,iOS上的图表控件已经有非常好的解决方案了。

    PNChart:https://github.com/kevinzhow/PNChart

    这个控件是是挺不错了,喜欢的朋友可以看看,本文很多地方借鉴了PNChart,就当学习源码也可以

    动手动手

     先上图先上图,配色直接用PNChart的了,还蛮喜欢这种配色风格,一直不太喜欢把手机横过来,所以做了个竖版的,还有很多不完善,学的时间也短,大家别见笑哈~

    ps:附带赠送双色球号码一注,大家可以去买,万一中了呢,由于女朋友老爹热爱福利事业,就写一个给他老人家玩玩,具体实现有人需要在贴吧,哈哈,我就是这么骗回复的 

                       

    相关知识点

     毕竟是新手入门的东西,列一下相关的知识点,如果后面有时间再一个个展开吧

    OC语法方面:

    NSArray,NSString,@interface,@property,@nonatomic,@implementation,id,alloc等

    iOS方面:

    UIView,CAShapeLayer,UIBezierPath,CATextLayer,UIColor,CABasicAnimation

    撸代码

    言归正传,看看代码实现部分

    首先需要定义LZBar.h,包含了基本的声明,当然还缺少了X轴的文字说明,大家可以自己扩展下:

     1 #import <UIKit/UIKit.h>
     2 #import <QuartzCore/QuartzCore.h>
     3 
     4 @interface LZBar : UIView{
     5     CAShapeLayer *backgroundLayer; //背景层
     6     UIBezierPath *backgroundPath; //背景赛贝尔路径
     7     CAShapeLayer *barLayer; //柱状层
     8     UIBezierPath *barPath; //柱状赛贝尔路径
     9     CATextLayer *textLayer; //数值文字显示层
    10     CATextLayer *tittleLayer; //标题文字说明层
    11 }
    12 
    13 @property (nonatomic) UIColor *backgroundColor;//背景色
    14 @property (nonatomic) UIColor *barColor;//柱的颜色
    15 @property (nonatomic) float barProgress;//柱子长度 0-1之间
    16 @property (nonatomic) float barWidth;//柱子宽度
    17 @property (nonatomic) NSString *barText;//数值
    18 @property (nonatomic) NSString *barTittle;//标题
    19 
    20 @end
      1 #import "LZBar.h"
      2 
      3 @implementation LZBar
      4 
      5 //初始化
      6 - (id)initWithFrame:(CGRect)frame
      7 {
      8     self = [super initWithFrame:frame];
      9     if (self)
     10     {
     11         backgroundLayer = [CAShapeLayer new];
     12         [self.layer addSublayer:backgroundLayer];
     13         backgroundLayer.strokeColor = LZGrey.CGColor;
     14         backgroundLayer.frame = self.bounds;
     15         
     16         barLayer = [CAShapeLayer new];
     17         [self.layer addSublayer:barLayer];
     18         barLayer.strokeColor = LZGreen.CGColor;
     19         barLayer.lineCap = kCALineCapButt;
     20         barLayer.frame = self.bounds;
     21         
     22         self.barWidth = self.bounds.size.width;
     23     }
     24     return self;
     25 }
     26 
     27 //设置背景
     28 - (void)setBackground
     29 {
     30     backgroundPath = [UIBezierPath bezierPath];
     31     [backgroundPath moveToPoint:CGPointMake(self.bounds.origin.x, self.bounds.origin.y+self.bounds.origin.y+self.bounds.size.height/2)];
     32     [backgroundPath addLineToPoint:CGPointMake(self.bounds.size.width, self.bounds.origin.y+self.bounds.origin.y+self.bounds.size.height/2)];
     33     [backgroundPath setLineWidth:_barWidth];
     34     [backgroundPath setLineCapStyle:kCGLineCapSquare];
     35     backgroundLayer.path = backgroundPath.CGPath;
     36 }
     37 
     38 //设置百分百(显示动画)
     39 - (void)setProgress
     40 {
     41     barPath = [UIBezierPath bezierPath];
     42     [barPath moveToPoint:CGPointMake(self.bounds.origin.x, self.bounds.origin.y+self.bounds.origin.y+self.bounds.size.height/2)];
     43     [barPath addLineToPoint:CGPointMake(self.bounds.size.width*_barProgress, self.bounds.origin.y+self.bounds.origin.y+self.bounds.size.height/2)];
     44     [barPath setLineWidth:_barWidth];
     45     [barPath setLineCapStyle:kCGLineCapSquare];
     46     
     47     CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
     48     pathAnimation.duration = 1.0;
     49     pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
     50     pathAnimation.fromValue = @0.0f;
     51     pathAnimation.toValue = @1.0f;
     52     [barLayer addAnimation:pathAnimation forKey:nil];
     53     
     54     barLayer.strokeEnd = 1.0;
     55 
     56     barLayer.path = barPath.CGPath;
     57 }
     58 
     59 //设置柱子的宽度
     60 - (void)setBarWidth:(float)progressWidth
     61 {
     62     _barWidth = progressWidth;
     63     backgroundLayer.lineWidth = _barWidth;
     64     barLayer.lineWidth = _barWidth;
     65     
     66     [self setBackground];
     67     [self setProgress];
     68 }
     69 
     70 //设置背景色
     71 - (void)setBackgroundColor:(UIColor *)backgroundColor
     72 {
     73     backgroundLayer.strokeColor = backgroundColor.CGColor;
     74 }
     75 
     76 //设置柱子颜色
     77 - (void)setBarColor:(UIColor *)barColor
     78 {
     79     barLayer.strokeColor = barColor.CGColor;
     80 }
     81 
     82 //设置柱子进度
     83 - (void)setBarProgress:(float)progress
     84 {
     85     _barProgress = progress;
     86     [self setProgress];
     87 }
     88 
     89 //设置数值
     90 - (void)setBarText:(NSString*)text{
     91     textLayer = [CATextLayer layer];
     92     textLayer.string = text;
     93     textLayer.foregroundColor = [[UIColor blackColor] CGColor];
     94     textLayer.fontSize = 16;
     95     textLayer.alignmentMode = kCAAlignmentLeft;
     96     
     97     textLayer.bounds = barLayer.bounds;
     98     textLayer.position = CGPointMake(self.bounds.size.width*3/2 + 5 , self.bounds.size.height/2);
     99     CABasicAnimation *fade = [self fadeAnimation];
    100     [textLayer addAnimation:fade forKey:nil];
    101     [self.layer addSublayer:textLayer];
    102 }
    103 
    104 //设置标题
    105 - (void)setBarTittle:(NSString*)tittle{
    106     tittleLayer = [CATextLayer layer];
    107     tittleLayer.string = tittle;
    108     tittleLayer.foregroundColor = [[UIColor blackColor] CGColor];
    109     tittleLayer.fontSize = 16;
    110     tittleLayer.alignmentMode = kCAAlignmentRight;
    111 
    112     tittleLayer.bounds = barLayer.bounds;
    113     tittleLayer.position = CGPointMake(-self.bounds.size.width/2 - 5 , self.bounds.size.height/2);
    114     CABasicAnimation *fade = [self fadeAnimation];
    115     [tittleLayer addAnimation:fade forKey:nil];
    116     [self.layer addSublayer:tittleLayer];
    117 }
    118 
    119 //渐变动画
    120 -(CABasicAnimation*)fadeAnimation
    121 {
    122     CABasicAnimation* fadeAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
    123     fadeAnimation.fromValue = [NSNumber numberWithFloat:0.0];
    124     fadeAnimation.toValue = [NSNumber numberWithFloat:1.0];
    125     fadeAnimation.duration = 2.0;
    126     
    127     return fadeAnimation;
    128 }
    129 @end

     有了Bar之后问题就变的简单的多了,我们可以在构建一个Chart,方便我们直接使用,防止内容过长,看起来累,代码我就折叠了~

     1 #import <UIKit/UIKit.h>
     2 
     3 @interface LZChart : UIView{
     4     CGSize size;//图表大小
     5 }
     6 
     7 @property (nonatomic)NSArray *numLabels;//
     8 @property (nonatomic)NSArray *nameLabels;//名称
     9 @property (nonatomic)float maxNum;//最大值
    10 
    11 @property (nonatomic)NSInteger barSpacing;//两根柱状图的间距
    12 
    13 @property (nonatomic) CGFloat chartMarginLeft;
    14 @property (nonatomic) CGFloat chartMarginRight;
    15 @property (nonatomic) CGFloat chartMarginTop;
    16 @property (nonatomic) CGFloat chartMarginBottom;
    17 
    18 - (void)show;//现实图标
    19 
    20 @end
    LZChart.h
     1 #import "LZChart.h"
     2 #import "LZBar.h"
     3 
     4 @implementation LZChart
     5 
     6 -(id)initWithFrame:(CGRect)frame{
     7     self = [super initWithFrame:frame];
     8     if (self) {
     9         size = frame.size;
    10         _chartMarginTop = 30.0;
    11         _chartMarginBottom = 30.0;
    12         _chartMarginLeft = 30.0;
    13         _chartMarginRight = 30.0;
    14         _barSpacing = 20;
    15     }
    16     return self;
    17 }
    18 
    19 -(void)show{
    20     [self setMaxNum];
    21     
    22     float barCount = [_numLabels count];
    23     float barMaxWidth = size.width - _chartMarginLeft - _chartMarginRight ;
    24     float barHeight = (size.height - _chartMarginTop - _chartMarginBottom) / barCount - _barSpacing;
    25     //防止柱状图太粗
    26     if(barHeight > 25){
    27         barHeight = 25;
    28     }
    29     float barWidth = 0;
    30     
    31     for(int i = 0;i<barCount;i++){
    32         LZBar *bar = [[LZBar alloc] initWithFrame:CGRectMake(_chartMarginLeft, _chartMarginTop + i*(barHeight + _barSpacing), barMaxWidth, barHeight)];
    33         barWidth = [_numLabels[i] floatValue];
    34         bar.barProgress = barWidth/_maxNum;
    35         bar.barWidth = barHeight;
    36         bar.barText = [NSString stringWithFormat:@"%.1f",barWidth];
    37         bar.barTittle = [NSString stringWithFormat:@"%@",_nameLabels[i]];
    38         [self addSubview:bar];
    39     }
    40 }
    41 
    42 -(void)setMaxNum{
    43     _maxNum = 0;
    44     for (id num in _numLabels) {
    45         if ([num floatValue] > _maxNum) {
    46             _maxNum = [num floatValue] ;
    47         }
    48     }
    49 }
    50 @end
    LZChart.m

    然后在需要添加的UIView直接调用,是不是很容易呢

    1     LZChart *chart = [[LZChart alloc] initWithFrame:CGRectMake(30, 100, 300, 300)];
    2     chart.numLabels = [NSArray arrayWithObjects:@10,@2,@3,@4, nil];
    3     chart.nameLabels = [NSArray arrayWithObjects:@"第一",@"第二",@"第三",@"第四", nil];
    4     [self.view addSubview:chart];
    5     [chart show];

    最终效果:

     

    希望大家喜欢~

    博客地址: http://www.cnblogs.com/nightcat/
    博客版权: 本文以学习、研究和分享为主,欢迎转载,但必须在文章页面明显位置给出原文连接。
    如文中有不妥或者错误的地方还望高手的指出,以免误人子弟。如果觉得本文对您有所帮助请【推荐】一下!如果你有更好的建议,不妨留言一起讨论,共同进步! 再次感谢您耐心的读完本篇文章。

  • 相关阅读:
    考察数据结构(An Extensive Examination of Data Structures)
    考察数据结构——第一部分:数据结构简介[译]
    老生常谈
    使用DataSet的ReadXml和WriteXml方法
    要掌握Sql Server,我还差得远啊!
    新浪短信Web Service
    还是水晶报表
    两种报表组件的功能分析
    无限级分类(非递归算法/存储过程版/GUID主键)完整数据库示例_(4)显示记录
    c#方法中调用参数的值传递方式和引用传递方式,以及ref与out的区别
  • 原文地址:https://www.cnblogs.com/nightcat/p/ios_01.html
Copyright © 2011-2022 走看看