iOS折線圖實現(xiàn)(一)

最近一直在斷斷續(xù)續(xù)的搞一些簡單的動畫效果,感覺效果還不錯,其中也有很多道友對效果的實現(xiàn)提出了有意義的建議(十分感謝,等抽出時間會進行全面的修改),
1.雙曲線波浪動畫(http://www.itdecent.cn/p/7db295fd38eb)
2.環(huán)形倒計時動畫(http://www.itdecent.cn/p/d1d16dff33c9)
3.儀表式數(shù)字跳動動畫(http://www.itdecent.cn/p/0d6f50385861)

進入正題
一, 對于折線圖很容易明白 那就直接上效果啦

6月-29-2016 13-56-52.gif

1.老套路 先說一下思路,看效果 就很容易知道這個里面包括的大概技能點
貝塞爾曲線 和 背景顏色填充
1.劃線的方法有很多 我采用的是CGContextRef畫坐標(biāo)軸
2.然后CAGradientLayer 添加背景漸變顏色 和 貝塞爾畫橫坐標(biāo)線
思路大概就這些!!!!!

二, 功能實現(xiàn)
創(chuàng)建Uiview 就不說了
1.先話坐標(biāo)軸

- (void)drawRect:(CGRect)rect{
       /*******畫出坐標(biāo)軸********/
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 2.0);
    CGContextSetRGBStrokeColor(context, 1, 0, 0, 1);
    CGContextMoveToPoint(context, bounceX, bounceY);
    CGContextAddLineToPoint(context, bounceX, rect.size.height - bounceY);
    CGContextAddLineToPoint(context,rect.size.width -  bounceX, rect.size.height - bounceY);
    CGContextStrokePath(context);
    
      }

接著在橫豎坐標(biāo)軸上創(chuàng)建數(shù)據(jù)

#pragma mark 創(chuàng)建x軸的數(shù)據(jù)
- (void)createLabelX{
    CGFloat  month = 12;
    for (NSInteger i = 0; i < month; i++) {
        UILabel * LabelMonth = [[UILabel alloc]initWithFrame:CGRectMake((self.frame.size.width - 2*bounceX)/month * i + bounceX, self.frame.size.height - bounceY + bounceY*0.3, (self.frame.size.width - 2*bounceX)/month- 5, bounceY/2)];
 //       LabelMonth.backgroundColor = [UIColor greenColor];
        LabelMonth.tag = 1000 + i;
        LabelMonth.text = [NSString stringWithFormat:@"%ld月",i+1];
        LabelMonth.font = [UIFont systemFontOfSize:10];
        LabelMonth.transform = CGAffineTransformMakeRotation(M_PI * 0.3);
        [self addSubview:LabelMonth];
    }

}
#pragma mark 創(chuàng)建y軸數(shù)據(jù)
- (void)createLabelY{
    CGFloat Ydivision = 6;
    for (NSInteger i = 0; i < Ydivision; i++) {
        UILabel * labelYdivision = [[UILabel alloc]initWithFrame:CGRectMake(0, (self.frame.size.height - 2 * bounceY)/Ydivision *i + bounceX, bounceY, bounceY/2.0)];
     //   labelYdivision.backgroundColor = [UIColor greenColor];
        labelYdivision.tag = 2000 + i;
        labelYdivision.text = [NSString stringWithFormat:@"%.0f",(Ydivision - i)*100];
         labelYdivision.font = [UIFont systemFontOfSize:10];
        [self addSubview:labelYdivision];
    }
}
/*
這兩函數(shù)在 view的初始化方法里面調(diào)用
- (instancetype)initWithFrame:(CGRect)frame{
    if (self = [super initWithFrame:frame]) {
        self.backgroundColor = [UIColor whiteColor];
        [self createLabelX];
        [self createLabelY];
          }
    return self;
}

*/

看效果如下:


0FABF464-6908-43DC-BAEC-F88391ACB428.png

2.創(chuàng)建做顏色漸變背景

@interface ZXView ()
@property (nonatomic, strong) CAShapeLayer *lineChartLayer;
@property (nonatomic, strong)UIBezierPath * path1;
/** 漸變背景視圖 */
@property (nonatomic, strong) UIView *gradientBackgroundView;
/** 漸變圖層 */
@property (nonatomic, strong) CAGradientLayer *gradientLayer;
/** 顏色數(shù)組 */
@property (nonatomic, strong) NSMutableArray *gradientLayerColors;
@end

- (void)drawGradientBackgroundView {
    // 漸變背景視圖(不包含坐標(biāo)軸)
    self.gradientBackgroundView = [[UIView alloc] initWithFrame:CGRectMake(bounceX, bounceY, self.bounds.size.width - bounceX*2, self.bounds.size.height - 2*bounceY)];
    [self addSubview:self.gradientBackgroundView];
    /** 創(chuàng)建并設(shè)置漸變背景圖層 */
    //初始化CAGradientlayer對象,使它的大小為漸變背景視圖的大小
    self.gradientLayer = [CAGradientLayer layer];
    self.gradientLayer.frame = self.gradientBackgroundView.bounds;
    //設(shè)置漸變區(qū)域的起始和終止位置(范圍為0-1),即漸變路徑
    self.gradientLayer.startPoint = CGPointMake(0, 0.0);
    self.gradientLayer.endPoint = CGPointMake(1.0, 0.0);
    //設(shè)置顏色的漸變過程
    self.gradientLayerColors = [NSMutableArray arrayWithArray:@[(__bridge id)[UIColor colorWithRed:253 / 255.0 green:164 / 255.0 blue:8 / 255.0 alpha:1.0].CGColor, (__bridge id)[UIColor colorWithRed:251 / 255.0 green:37 / 255.0 blue:45 / 255.0 alpha:1.0].CGColor]];
    self.gradientLayer.colors = self.gradientLayerColors;
    //將CAGradientlayer對象添加在我們要設(shè)置背景色的視圖的layer層
    [self.gradientBackgroundView.layer addSublayer:self.gradientLayer];
     //[self.layer addSublayer:self.gradientLayer];
}
/* 這個方法還是再初始化方法里面調(diào)用
- (instancetype)initWithFrame:(CGRect)frame{
    if (self = [super initWithFrame:frame]) {
     //   self.my
        self.backgroundColor = [UIColor whiteColor];
        
        [self createLabelX];
        [self createLabelY];
        [self drawGradientBackgroundView];
       // [self setLineDash];
          }
    return self;
}

*/
5DCD7713-2EB4-42A0-B5CD-8F3AF6A419F3.png

如果你在糾結(jié)于 漸變顏色 的實現(xiàn) 或者 各個圖層是怎么加的 還有尺寸 怎么搞 ,我想我不會說的太多 (因為這需要親自實踐一下,原因二 我也說不太明白)
3.接下來畫虛線

#pragma mark 添加虛線
- (void)setLineDash{

    for (NSInteger i = 0;i < 6; i++ ) {
        CAShapeLayer * dashLayer = [CAShapeLayer layer];
          dashLayer.strokeColor = [UIColor whiteColor].CGColor;
        dashLayer.fillColor = [[UIColor clearColor] CGColor];
        // 默認(rèn)設(shè)置路徑寬度為0,使其在起始狀態(tài)下不顯示
        dashLayer.lineWidth = 1.0;


        UILabel * label1 = (UILabel*)[self viewWithTag:2000 + i];//獲取x軸數(shù)據(jù)label的位置根據(jù)其位置畫橫虛線
        
        UIBezierPath * path = [[UIBezierPath alloc]init];
        path.lineWidth = 1.0;
        UIColor * color = [UIColor blueColor];
        
        [color set];
 [path moveToPoint:CGPointMake( 0, label1.frame.origin.y - bounceY)];
 [path addLineToPoint:CGPointMake(self.frame.size.width - 2*bounceX,label1.frame.origin.y - bounceY)];
        CGFloat dash[] = {10,10};
        [path setLineDash:dash count:2 phase:10];
        [path stroke];
        dashLayer.path = path.CGPath;
        [self.gradientBackgroundView.layer addSublayer:dashLayer];
         }
}
/* 這個方法還是再初始化方法里面調(diào)用
- (instancetype)initWithFrame:(CGRect)frame{
    if (self = [super initWithFrame:frame]) {
    
        self.backgroundColor = [UIColor whiteColor];
        
        [self createLabelX];
        [self createLabelY];
        [self drawGradientBackgroundView];
        [self setLineDash];
          }
    return self;
}

*/

效果如下:


20BEC8AC-5FB2-4BBD-A661-8D2F5A6E9C8E.png

可以看出來 畫出來的虛線 并不是虛線 在這個我也很疑問 ?是上面畫虛線的地方寫錯啦 么? 該怎么寫 希望道友告知!!!

4.接下來就是最主要的 畫折線

#pragma mark 畫折線圖
- (void)dravLine{
    
    UILabel * label = (UILabel*)[self viewWithTag:1000];//根據(jù)橫坐標(biāo)上面的label 獲取直線關(guān)鍵點的x 值
    UIBezierPath * path = [[UIBezierPath alloc]init];
    path.lineWidth = 1.0;
    self.path1 = path;
    UIColor * color = [UIColor greenColor];
    [color set];
    [path moveToPoint:CGPointMake( label.frame.origin.x - bounceX, (600 -arc4random()%600) /600.0 * (self.frame.size.height - bounceY*2 )  )];

    //創(chuàng)建折現(xiàn)點標(biāo)記
    for (NSInteger i = 1; i< 12; i++) {
        UILabel * label1 = (UILabel*)[self viewWithTag:1000 + i];
        CGFloat  arc = arc4random()%600;  //折線點目前給的是隨機數(shù)
        [path addLineToPoint:CGPointMake(label1.frame.origin.x - bounceX,  (600 -arc) /600.0 * (self.frame.size.height - bounceY*2 ) )];
        UILabel * falglabel = [[UILabel alloc]initWithFrame:CGRectMake(label1.frame.origin.x , (600 -arc) /600.0 * (self.frame.size.height - bounceY*2 )+ bounceY  , 30, 15)];
      //  falglabel.backgroundColor = [UIColor blueColor];
        falglabel.tag = 3000+ i;
        falglabel.text = [NSString stringWithFormat:@"%.1f",arc];
        falglabel.font = [UIFont systemFontOfSize:8.0];
        [self addSubview:falglabel];
    }
    // [path stroke];
    
    self.lineChartLayer = [CAShapeLayer layer];
    self.lineChartLayer.path = path.CGPath;
    self.lineChartLayer.strokeColor = [UIColor whiteColor].CGColor;
    self.lineChartLayer.fillColor = [[UIColor clearColor] CGColor];
    // 默認(rèn)設(shè)置路徑寬度為0,使其在起始狀態(tài)下不顯示
    self.lineChartLayer.lineWidth = 0;
    self.lineChartLayer.lineCap = kCALineCapRound;
    self.lineChartLayer.lineJoin = kCALineJoinRound;
    
    [self.gradientBackgroundView.layer addSublayer:self.lineChartLayer];//直接添加導(dǎo)視圖上
 //   self.gradientBackgroundView.layer.mask = self.lineChartLayer;//添加到漸變圖層

}

接下來就應(yīng)該是 實現(xiàn)劃線的動畫啦啦

#pragma mark 點擊重新繪制折線和背景
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    countq++;
    if (countq%2 == 0) {
//點一下刪除折線 和轉(zhuǎn)折點數(shù)據(jù)
        [self.lineChartLayer removeFromSuperlayer];
        for (NSInteger i = 0; i < 12; i++) {
            UILabel * label = (UILabel*)[self viewWithTag:3000 + i];
            [label removeFromSuperview];
        }
    }else{

        [self dravLine];

    self.lineChartLayer.lineWidth = 2;
    CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    pathAnimation.duration = 3;
    pathAnimation.repeatCount = 1;
    pathAnimation.removedOnCompletion = YES;
    pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
    pathAnimation.toValue = [NSNumber numberWithFloat:1.0f];
    // 設(shè)置動畫代理,動畫結(jié)束時添加一個標(biāo)簽,顯示折線終點的信息
    pathAnimation.delegate = self;
    [self.lineChartLayer addAnimation:pathAnimation forKey:@"strokeEnd"];
        //[self setNeedsDisplay];
    }
}

那么好到這里就完全完畢了 ,看到這里不免感覺好簡單,
畫坐標(biāo)軸 >>>>畫背景 >>>>劃線 >>>>動起來 就是四部而已.但是實現(xiàn)起來去會遇到很多問題(尤其是第一次搞得道友).接下來有時間會搞成可以直接調(diào)用的類 方便以后 使用.

道友多多指教!!!!!(稍后上傳代碼)

更新: 第二篇的地址http://www.itdecent.cn/p/1c6a119149bd
本片的git地址([https://git.oschina.net/GAOZEJIAN/zhexiantu_one.git](https://git.oschina.net/GAOZEJIAN/zhexiantu_one.git))
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,035評論 4 61
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,725評論 25 709
  • 愛自己,就是 細心呵護好自己會呼吸的身體,不要使他受到任何的損害,因為這個身體是生命修煉的載體。 愛自己,就是 無...
    世界因我更美麗閱讀 4,150評論 2 4
  • 周日晚上,收到女兒班主任在家長群里發(fā)的消息,說這次她班數(shù)學(xué)測驗全班只有一個人及格。我感覺到自己的不舒服。退出群界面...
    此時的寶丹閱讀 396評論 0 2
  • 汽車沿著西行的路線一直往前走,距離送別的人越來越遠,終于走向遠處,也許再無交集。遠方有詩,浪漫棲居;這里無趣,難再...
    辛未先生閱讀 782評論 0 0

友情鏈接更多精彩內(nèi)容