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

时间: 2024-12-05 06:52:46

iOS简易柱状图(带动画)--新手入门篇的相关文章

IOS的一个带动画的多项选择的控件(二)

然后我们来写:TypeSelectView 这个比较简单,我们只要只要每个TypeView的位置,然后作为自己的subview就好了 @interface TypeSelectView : UIView @property(nonatomic) BOOL bShown; @property(nonatomic, strong) TypeView* curSelectedView; -(id)initWithFrame:(CGRect)frame searchType:(int)type; @en

IOS的一个带动画的多项选择的控件(一)

先上效果图: 这个程序分2个层次,一个是顶部的带UITextField的bar,一个是下拉选择的view,下拉选择的view带有4个自定义的UIView 我们先定义一个UIViewController叫MyViewController,然后顶部的bar叫TopBarView,下拉选择的view叫TypeSelectView,像UIButton的自定义的view叫做TypeView TypeView有两种状态,如果手指触摸到的item就是选中状态,所以TypeSelectView应该有个属性表示当

MYSQL新手入门篇

MYSQL新手入门篇 一.数据库的简介 什么是数据库? 数据的仓库,如:在atm的实例中我们创建一个db目录称之为数据库 什么是 MySQL.Oracle.SQLite.Access.MS SQL Server等 ? 他们是数据库软件,主要功能为两部分:1.讲数据保存到内存或者文件.2.接受特定的命令对数据进行操作 什么是SQL? 上述问题说过,数据库要接受特定的命令,这个命令就是用SQL编写,他是结构化查询语言(Structured Query Language)的缩写,一种专门与数据库交互的

基于Rebound制造绚丽的动画效果-入门篇

基于Rebound制造绚丽的动画效果-入门篇 Rebound是什么? Rebound是一个来自 Facebook 公司的 Java物理和动画库.Rebound spring 模型可用于创建动画,让你感觉很自然. Rebound的运作原理是什么? Rebound拥有两个参数:tension.friction. tension是张力,拉力. friction是摩擦力. 演示: tension:50,friction:1 rebound_t50_f1.gif 拉力为50时,摩擦为1.摩擦对拉力的损耗十

entity framework 新手入门篇(4)-entity framework扩展之 entityframework.extended

对于EF的操作,我们已经有了大概的了解了,但对于实战来说,似乎还欠缺着一些常用的功能,那就是批量的删除,更新数据. 承接上面的部分,我们有一个叫做House的数据库,其中包含house表和seller表. 一.使用原生EF如何实现批量删除和修改? //批量修改 public static bool UpdateAllPrice(decimal price) { bool isOk = false; using (HouseEntities db = new HouseEntities()) {

entity framework 新手入门篇(1)-建立模型

entity framework是微软官方免费提供给大家的一套ORM(Object Relational Mapping对象关系映射)解决方案.它不仅可以帮助我们解决数据缓存的问题,还能在最小的开销下实现完全的OO(Object Oriented面向对象)编程.实乃中小项目中敏捷开发的一大福祉.博主作为一只刚入本行的菜鸟,有幸参加开发了几个使用entity framework(以下简称EF)的项目,虽然在这些项目开发的过程中,走了许多的弯路,网上的资料也不甚齐全.在摸爬滚打了一年之后,也算有了一

entity framework 新手入门篇(3)-entity framework实现orderby,count,groupby,like,in,分页等

前面我们已经学习了entityframework的基本的增删改查,今天,我们将在EF中实现一些更加贴近于实际功能的SQL方法. 承接上面的部分,我们有一个叫做House的数据库,其中包含house表和seller表. 在本次学习之前,我们先要了解一个神奇的接口,iqueryable这个接口类似于ienumable,但并不完全相同,Iqueryable是可查询类型需要实现的最重要的接口,在其Count,ToList,ToArray之后才会真正执行查询,所以,为了保证性能,请尽量在最后一步在进行Co

entity framework 新手入门篇(1.5)-lambda表达式与linq

在建立好了EF模型之后,先不着急使用它,在使用它之前,你还需要了解两个相关的技术,lambda表达式与linq. 作为微软C#语言中重要的语法糖-lambda表达式与LINQ,本质都是一个方法,以lambda表达式为例: x=>x+1;就是一个完整的lambda表达式. 其等同于一个匿名的方法: int anonymous(int x) { return x+1; } 考虑一下这个方法中最重要的部分,也就两个部分:传入的参数,返回的参数. 返回值类型,参数类型都是可以进行推断的,就像C#中的VA

entity framework 新手入门篇(2)-entity framework基本的增删改查

经过前两节的简单描述,终于可以进入entity framework的使用部分了.本节将对entity framework原生的增删改查进行讲解. 承接上面的部分,我们有一个叫做House的数据库,其中包含house表和seller表. 一.entity framework 相关类的理解. 首先,House数据库在映射后会生成一个名为HouseEntities的类,这个类我们称之为数据上下文,可以简单的理解为数据库的部分映射(如果映射了全部的表,视图,存储过程,则可看作全部映射). 使用数据库的时