iOS仿支付寶賬單餅狀圖

前言:

  • 這段時間項目做了一個賬單查詢的頁面使用到了餅狀圖,支付寶賬單那個餅狀圖,就簡單的封裝了一個給大家看看,使用的基本技術也就是使用UIBezierPath繪制柱狀圖路徑,再把CAShapeLayer和UIBezierPath建立關系,最后使用CABasicAnimation實現簡單的動畫效果。

先看下效果圖:動畫太快了注意看吧

Untitled.gif

1.繪制餅狀圖

繪制餅狀圖計算每個扇形弧度中心點坐標記錄成員變量給指示線起點&指示線起點圓點使用

#pragma mark ------ 繪制餅狀圖 -------
- (void)addPieChart:(CAShapeLayer *)layer
       andArcCenter:(CGPoint)ArcCenter
     andStart_Angle:(CGFloat)start_Angle
       andend_Angle:(CGFloat)end_Angle
   andPieChartWidht:(CGFloat)PieChartWidht
andandPieChartColor:(UIColor *)andPieChartColor{
    UIBezierPath * progressPath = [UIBezierPath bezierPathWithArcCenter:ArcCenter radius:PieChartRadius startAngle:DEGREES_TO_VALUE(start_Angle) endAngle:DEGREES_TO_VALUE(end_Angle) clockwise:YES];
    layer.path = progressPath.CGPath;
    layer.lineWidth = PieChartWidht;
    layer.strokeColor = andPieChartColor.CGColor;
    // 計算存儲圓弧中心點到數組
    // 弧度的中心角度
    CGFloat RadianCentreCoordinate = (DEGREES_TO_VALUE(start_Angle) + DEGREES_TO_VALUE(end_Angle)) / 2.0;
    // 記錄小圓的中心點(折現起始點)
    ArcCentreCoordinate.x = ArcCenter.x+(PieChartRadius+40) * cos(RadianCentreCoordinate);
    ArcCentreCoordinate.y = ArcCenter.y+(PieChartRadius+40) * sin(RadianCentreCoordinate);
}

2.餅狀圖動畫添加

餅狀圖繪制是基于UIBezierPath所有添加動畫使用CABasicAnimation

#pragma mark ------ 餅狀圖動畫添加 -------
- (void)addPieChart:(CAShapeLayer *)layer
       andArcCenter:(CGPoint)ArcCenter
     andStart_Angle:(CGFloat)start_Angle
       andend_Angle:(CGFloat)end_Angle
   andPieChartWidht:(CGFloat)PieChartWidht
   andPieChartColor:(UIColor *)PieChartColor
           animated:(BOOL)animated{
    [self addPieChart:layer andArcCenter:ArcCenter andStart_Angle:start_Angle andend_Angle:end_Angle andPieChartWidht:PieChartWidht andandPieChartColor:PieChartColor];
    CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    pathAnimation.duration = end_Angle*0.01;
    pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
    pathAnimation.toValue = [NSNumber numberWithFloat:1.0f];
    [layer addAnimation:pathAnimation forKey:nil];
}

3.繪制指示線

這個指示線挺煩,坐標系原理你們自己看看吧。

#pragma mark ------ 繪制指示線 -------
- (CGPoint)addIndicatrixLine:(CAShapeLayer *)layer
      andOriginCoordinate:(CGPoint)OriginCoordinate
  andIndicatrixLineLength:(CGFloat)IndicatrixLineLength
   andIndicatrixLineWidth:(CGFloat)IndicatrixLineWidth
   andIndicatrixLineColor:(UIColor *)IndicatrixLineColor{
    
    //起點坐標
    CGFloat IndicatrixLine_Origin_CoordInateX = OriginCoordinate.x;
    CGFloat IndicatrixLine_Origin_CoordInateY = OriginCoordinate.y;
    //圓點坐標
    [self addIndicatrixLine_Origin_Style:CGPointMake(IndicatrixLine_Origin_CoordInateX, IndicatrixLine_Origin_CoordInateY) andColor:IndicatrixLineColor];
    //終點坐標
    CGFloat IndicatrixLine_End_CoordInateX;
    CGFloat IndicatrixLine_End_CoordInateY;
    UIBezierPath * IndicatrixLine = [UIBezierPath bezierPath];
    //指示線第一段(小段)
    if (IndicatrixLine_Origin_CoordInateX < ARCCENTER.x) {
        if (IndicatrixLine_Origin_CoordInateY < ARCCENTER.y) {
            //終點坐標
            IndicatrixLine_End_CoordInateX = OriginCoordinate.x-10;
            IndicatrixLine_End_CoordInateY = OriginCoordinate.y-10;
        }else{
            //終點坐標
            IndicatrixLine_End_CoordInateX = OriginCoordinate.x-10;
            IndicatrixLine_End_CoordInateY = OriginCoordinate.y+10;
        }
    }else{
        if (IndicatrixLine_Origin_CoordInateY < ARCCENTER.y) {
            //終點坐標
            IndicatrixLine_End_CoordInateX = OriginCoordinate.x+10;
            IndicatrixLine_End_CoordInateY = OriginCoordinate.y-10;
        }else{
            //終點坐標
            IndicatrixLine_End_CoordInateX = OriginCoordinate.x+10;
            IndicatrixLine_End_CoordInateY = OriginCoordinate.y+10;
        }
    }
    [IndicatrixLine moveToPoint:CGPointMake(IndicatrixLine_Origin_CoordInateX, IndicatrixLine_Origin_CoordInateY)];
    [IndicatrixLine addLineToPoint:CGPointMake(IndicatrixLine_End_CoordInateX, IndicatrixLine_End_CoordInateY)];
    //畫完第一段(小段)把小段的終點賦值給第二段(大段)當起點
    IndicatrixLine_Origin_CoordInateX = IndicatrixLine_End_CoordInateX;
    IndicatrixLine_Origin_CoordInateY = IndicatrixLine_End_CoordInateY;
    //指示線第二段(大段)
    if (IndicatrixLine_Origin_CoordInateX < ARCCENTER.x) {
        if (IndicatrixLine_Origin_CoordInateY < ARCCENTER.y) {
            //終點坐標
            IndicatrixLine_End_CoordInateX = OriginCoordinate.x-IndicatrixLineLength;
            IndicatrixLine_End_CoordInateY = OriginCoordinate.y-10;
        }else{
            //終點坐標
            IndicatrixLine_End_CoordInateX = OriginCoordinate.x-IndicatrixLineLength;
            IndicatrixLine_End_CoordInateY = OriginCoordinate.y+10;
        }
    }else{
        if (IndicatrixLine_Origin_CoordInateY < ARCCENTER.y) {
            //終點坐標
            IndicatrixLine_End_CoordInateX = OriginCoordinate.x+IndicatrixLineLength;
            IndicatrixLine_End_CoordInateY = OriginCoordinate.y-10;
        }else{
            //終點坐標
            IndicatrixLine_End_CoordInateX = OriginCoordinate.x+IndicatrixLineLength;
            IndicatrixLine_End_CoordInateY = OriginCoordinate.y+10;
        }
    }
    [IndicatrixLine moveToPoint:CGPointMake(IndicatrixLine_Origin_CoordInateX, IndicatrixLine_Origin_CoordInateY)];
    [IndicatrixLine addLineToPoint:CGPointMake(IndicatrixLine_End_CoordInateX, IndicatrixLine_End_CoordInateY)];
    layer.path = IndicatrixLine.CGPath;
    layer.lineWidth = IndicatrixLineWidth;
    layer.strokeColor = IndicatrixLineColor.CGColor;
    return CGPointMake(IndicatrixLine_End_CoordInateX, IndicatrixLine_End_CoordInateY);
}

4.指示線添加動畫

和餅狀圖動畫添加是一樣的

#pragma mark ------ 指示線動畫添加 -------
- (CGPoint)addIndicatrixLine:(CAShapeLayer *)layer
      andOriginCoordinate:(CGPoint)OriginCoordinate
  andIndicatrixLineLength:(CGFloat)IndicatrixLineLength
   andIndicatrixLineWidth:(CGFloat)IndicatrixLineWidth
   andIndicatrixLineColor:(UIColor *)IndicatrixLineColor
                 animated:(BOOL)animated{
   CGPoint TextCoordinate = [self addIndicatrixLine:layer andOriginCoordinate:OriginCoordinate andIndicatrixLineLength:IndicatrixLineLength andIndicatrixLineWidth:IndicatrixLineWidth andIndicatrixLineColor:IndicatrixLineColor];
    CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    pathAnimation.duration = IndicatrixLineLength*0.01;
    pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
    pathAnimation.toValue = [NSNumber numberWithFloat:1.0f];
    [layer addAnimation:pathAnimation forKey:nil];
    return TextCoordinate;
}

5.指示線起點樣式

這個是繪制了一個小圓點作為指示線起點

#pragma mark ------ 繪制指示線起點樣式 -------
- (void)addIndicatrixLine_Origin_Style:(CGPoint)coordinate
                          andColor:(UIColor *)indicatrixLineColor{
    CAShapeLayer *circleLayer = [CAShapeLayer layer];
    // 指定frame,只是為了設置寬度和高度
    circleLayer.frame = CGRectMake(0, 0, 2, 2);
    // 設置居中顯示
    circleLayer.position = CGPointMake(coordinate.x, coordinate.y);
    // 設置填充顏色
    circleLayer.fillColor = [UIColor clearColor].CGColor;
    // 設置線寬
    circleLayer.lineWidth = 2.0;
    // 設置線的顏色
    circleLayer.strokeColor = indicatrixLineColor.CGColor;
    // 使用UIBezierPath創建路徑
    CGRect frame = CGRectMake(0, 0, 2, 2);
    UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:frame];
    // 設置CAShapeLayer與UIBezierPath關聯
    circleLayer.path = circlePath.CGPath;
    // 將CAShaperLayer放到某個層上顯示
    [self.layer addSublayer:circleLayer];
}

5.指示線上下文字繪制

指示線上下文字繪制這個么什么好說的

#pragma mark ------ 繪制指示文字 -------
- (void)addHintText:(CGPoint)TextCoordinate
       andabovetext:(NSString *)abovetext
        andDowntext:(NSString *)Downtext
        andTextFont:(CGFloat)font
       andTextColor:(UIColor *)color{
    // 上面Size
    CGSize abovetextSize = [abovetext sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:font]}];
    // 下面Size
    CGSize DowntextSize = [Downtext sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:font]}];
    //上面文字坐標
    CGFloat abovetextCoordinateX;
    CGFloat abovetextCoordinateY;
    //下面文字坐標
    CGFloat DowntextCoordinateX;
    CGFloat DowntextCoordinateY;
    if (ARCCENTER.x < TextCoordinate.x) {
        abovetextCoordinateX = TextCoordinate.x-abovetextSize.width;
        abovetextCoordinateY = TextCoordinate.y-abovetextSize.height;
        DowntextCoordinateX = TextCoordinate.x-DowntextSize.width;
        DowntextCoordinateY = TextCoordinate.y;
    }else{
        abovetextCoordinateX = TextCoordinate.x;
        abovetextCoordinateY = TextCoordinate.y-abovetextSize.height;
        DowntextCoordinateX = TextCoordinate.x;
        DowntextCoordinateY = TextCoordinate.y;
    }
    NSMutableParagraphStyle * paragraph = [[NSMutableParagraphStyle alloc]init];
    paragraph.alignment = NSTextAlignmentLeft;
    //指引線上面的數字
    [abovetext drawAtPoint:CGPointMake(abovetextCoordinateX, abovetextCoordinateY) withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:font],NSForegroundColorAttributeName:color,NSParagraphStyleAttributeName:paragraph}];
    //指示線下面的文字
    [Downtext drawAtPoint:CGPointMake(DowntextCoordinateX, DowntextCoordinateY)
                    withAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:font],
                                     NSForegroundColorAttributeName:color,
                                     NSParagraphStyleAttributeName:paragraph}];
}

6. drawRect繪制調用

    - (void)drawRect:(CGRect)rect {
        // Drawing code
        NSArray * RedAarray = @[@"46",@"255",@"62",@"254",@"253",@"153",@"110"];
        NSArray * greenArray = @[@"191",@"48",@"209",@"199",@"109",@"208",@"123"];
        NSArray * blueArray = @[@"238",@"145",@"185",@"17",@"31",@"60",@"254"];
        for (int i = 0; i < _ArcCentreCoordinateAll.count; i++) {
            CAShapeLayer * progressLayer = [CAShapeLayer new];
            [self.layer addSublayer:progressLayer];
            progressLayer.fillColor = nil;
            progressLayer.frame = self.bounds;
            end = start+[[_ArcCentreCoordinateAll objectAtIndex:i] floatValue];
            NSMutableArray * startORendArray =  [[NSMutableArray alloc]init];
            [startORendArray addObject:[NSString stringWithFormat:@"%f",start]];
            [startORendArray addObject:[NSString stringWithFormat:@"%f",end]];
            start = end;
            /*
             @1.addPieChart:CAShapeLayer對象
             @2.andArcCenter:餅狀圖中心坐標
             @3.andStart_Angle:餅狀圖起點位置
             @4.andend_Angle:餅狀圖結束點位置
             @5.andPieChartColor:餅狀圖顏色
             @6.animated:是否添加動畫
             */
            [self addPieChart:progressLayer
                 andArcCenter:ARCCENTER
               andStart_Angle:[startORendArray[0] floatValue]
                 andend_Angle:[startORendArray[1] floatValue]
             andPieChartWidht:_PieChartWidth
             andPieChartColor:[UIColor colorWithRed:[[RedAarray objectAtIndex:i] intValue]/255.0  green:[[greenArray objectAtIndex:i] intValue]/255.0 blue:[[blueArray objectAtIndex:i] intValue]/255.0 alpha:1]
             animated:YES];
            CAShapeLayer * IndicatrixLayer =  [CAShapeLayer new];
            [self.layer addSublayer:IndicatrixLayer];
            IndicatrixLayer.fillColor = nil;
            IndicatrixLayer.frame = self.bounds;
            /*
             @1.addIndicatrixLine:CAShapeLayer對象
             @2.andOriginCoordinate:指示線&線帽起點坐標
             @3.andIndicatrixLineLength:指示線長度
             @4.andIndicatrixLineLength:指示線寬度
             @5.andIndicatrixLineColor:指示線顏色
             @6.animated:是否添加動畫
             */
            CGPoint TextCoordinate =  [self addIndicatrixLine:IndicatrixLayer
        andOriginCoordinate:ArcCentreCoordinate
    andIndicatrixLineLength:_IndicatrixLineLength
     andIndicatrixLineWidth:_IndicatrixLineWidth
     andIndicatrixLineColor:[UIColor colorWithRed:[[RedAarray objectAtIndex:i] intValue]/255.0  green:[[greenArray objectAtIndex:i] intValue]/255.0 blue:[[blueArray objectAtIndex:i] intValue]/255.0 alpha:1]
                   animated:YES];
            /*
             @1.addHintText:文字坐標
             @2.andabovetext:上面文字
             @3.andDowntext:下面文字
             @4.andTextFont:文字大小
             @5.andTextColor:文字顏色
             */
            [self addHintText:TextCoordinate
         andabovetext:_aboveHintTextAttayAll[i]
          andDowntext:_belowHintTextAttayAll[i]
          andTextFont:_HintTextFont
         andTextColor:_HintTextColor];
        }
    }
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容