美文网首页iOS动画相关iOS今日看点
iOS - 关于百分比圆环的解读

iOS - 关于百分比圆环的解读

作者: 麦穗0615 | 来源:发表于2016-11-29 18:47 被阅读537次
    前言:

    百分比圆环几乎是所有项目,中都会有的。针对于下面的Demo,我们采取双圆的形式,进行百分比圆环的案例分析,并且封装后,以方便备用。

    案例展示

    yuanhuan.gif

    在这当中,有以下几个难点,需要我们清楚:

    • 1.画圆弧利用的是贝塞尔曲线,我们必须清楚显示圆环和辅助圆环的起点角度和终点角度。
    • 2.显示圆环和辅助圆环的起点相同,终点不同
    • 3.显示圆环和辅助圆环重合(半径相同,位置相同),显示圆环的终点小于等于辅助圆环的终点

    必须理解一下三幅图
    第一幅图


    第二幅图

    通过上图,我们可以这样想,终点的弧度点 - 起点弧度点 = 整个圆弧的弧度 ,整个圆弧的弧度,我们可以把它看成0%~100%这样的百分比,例如:在用20%乘以整个圆弧的弧度这个就说明 ,在整个弧度中占有20%是多少。求出来之后在加上起点,就是显示圆的终点。

    第三幅图


    通过上幅图,我们要知道起点和终点是怎么平行在一条线上。

    代码示例
    ZYCircle.h

    #import <UIKit/UIKit.h>
    
    @interface ZYCircle : UIView
    //起点 角度
    @property(nonatomic) CGFloat startAngle;
    //终点 角度
     @property(nonatomic)CGFloat endInnerAngle;
    //线宽
    @property(nonatomic)CGFloat lineWith;
    //百分比数字
    @property (nonatomic)CGFloat percentage;
    //基准圆环颜色
    @property(nonatomic,strong)UIColor *unfillColor;
    //显示圆环颜色
    @property(nonatomic,strong)UIColor *fillColor;
    //中心数据显示标签
    @property (nonatomic ,strong)UILabel *centerLable;
    
    - (instancetype) initWithFrame:(CGRect)frame;
    
    @end
    

    ZYCircle.m
    #import "ZYCircle.h"
    #define DEGREES_TO_RADIANS(degrees) ((M_PI * degrees)/ 180)
    @interface ZYCircle ()

    @property(nonatomic) CGPoint CGPoinCerter;
    @property(nonatomic) CGFloat endAngle;
    @property(nonatomic) BOOL clockwise;
    
    @end
    
    @implementation ZYCircle
    {
        CGFloat _radius;
    }
    
    -(instancetype)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
    if (self) {
        self.lineWith = 10.0;
        self.fillColor = [UIColor greenColor];
        self.unfillColor = [UIColor lightGrayColor];
        self.clockwise = YES;
        self.backgroundColor = [UIColor clearColor];
        self.percentage = 0;
        self.startAngle = 180;
        self.endAngle = 360;
    }
    
    return self;
    }
    
    #pragma mark setMethod
    /**
     *  画图函数
     *
     *  @param rect rect description
     */
    -(void)drawRect:(CGRect)rect{
        [self initData];
        [self drawMiddlecircle];
        [self drawOutCCircle];
    }
    
    -(void)initData
    {
    >
    //中心标签设置
    CGFloat center =MIN(self.bounds.size.height/2, self.bounds.size.width/2);
    self.CGPoinCerter = CGPointMake(center, center);
    self.centerLable = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 2*center, 2*center)];
    self.centerLable.textAlignment=NSTextAlignmentCenter;
    self.centerLable.backgroundColor=[UIColor clearColor];
    self.centerLable.adjustsFontSizeToFitWidth = YES;
    self.centerLable.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
    self.contentMode = UIViewContentModeRedraw;
    [self addSubview: self.centerLable];
    
    //半径计算
    _radius = MIN(self.bounds.size.height/2-self.lineWith/2, self.bounds.size.width/2-self.lineWith/2);
    self.centerLable.font = [UIFont systemFontOfSize:_radius/3];
    self.centerLable.text = [NSString stringWithFormat:@"%.1lf%%",self.percentage*100];
    //起点与终点坐标
    self.endInnerAngle = DEGREES_TO_RADIANS(self.endInnerAngle);
    self.startAngle = DEGREES_TO_RADIANS(self.startAngle);
    self.endAngle = self.percentage*(self.endInnerAngle - self.startAngle) + self.startAngle;
    
    //0%标签
    UILabel *zeroPercentLable = [[UILabel alloc]init];
    zeroPercentLable.text = [NSString stringWithFormat:@"0%%"];
    CGFloat zeroPercentLableX =_radius + _radius*cos(self.startAngle);
    CGFloat zeroPercentLableY = _radius*sin(self.startAngle)+(self.startAngle>DEGREES_TO_RADIANS(180)?-_radius:_radius);
    zeroPercentLable.frame = CGRectMake(zeroPercentLableX, zeroPercentLableY+self.lineWith, 2.1*_radius/7.5 + 15, 25);
    zeroPercentLable.textAlignment = NSTextAlignmentCenter;
    zeroPercentLable.font = [UIFont boldSystemFontOfSize:_radius/7.5 ];
    zeroPercentLable.textColor = [UIColor orangeColor];
    [self addSubview:zeroPercentLable];
    //100%标签
    UILabel *hundredPercentLable = [[UILabel alloc]init];
    hundredPercentLable.text = [NSString stringWithFormat:@"100%%"];
    CGFloat hundredPercentLableX =_radius + _radius*cos(self.endInnerAngle)-8;
    CGFloat hundredPercentLableY = _radius*sin(self.endInnerAngle)+(self.endInnerAngle<DEGREES_TO_RADIANS(180)?-_radius:_radius);
    hundredPercentLable.frame = CGRectMake(hundredPercentLableX, hundredPercentLableY+self.lineWith, 2.9*_radius/7.5 + 15, 25);
    hundredPercentLable.textAlignment = NSTextAlignmentCenter;
    hundredPercentLable.font = [UIFont boldSystemFontOfSize:_radius/7.5 ];
    hundredPercentLable.textColor = [UIColor orangeColor];
    [self addSubview:hundredPercentLable];
    
    }
    
    #pragma mark - 利用layer的 strokeEnd、strokeStart和lineWidth 属性添加CA动画
    - (void)addAnimationOneOnLayer:(CAShapeLayer *)layer duration:(CFTimeInterval)duration
    {
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    animation.fromValue = @(0);
    animation.toValue = @(1);
    animation.duration = duration;
    [layer addAnimation:animation forKey:nil];
    }
    
    /**
     *  显示圆环
     */
    -(void )drawOutCCircle{
    UIBezierPath *bPath = [UIBezierPath bezierPathWithArcCenter:self.CGPoinCerter radius:_radius startAngle:self.startAngle endAngle:self.endAngle clockwise:self.clockwise];
    >
    CAShapeLayer *layer =  [CAShapeLayer layer];
    layer.lineWidth = self.lineWith;
    layer.lineCap = kCALineCapRound;
    layer.lineJoin = kCALineJoinRound;
    layer.strokeColor = self.fillColor.CGColor;
    layer.fillColor = nil;
    layer.path = bPath.CGPath;
    [self.layer addSublayer:layer];
    >
    [self addAnimationOneOnLayer:layer duration:1.0];
    }
    /**
     *  辅助圆环
     */
    -(void)drawMiddlecircle{
    UIBezierPath *cPath = [UIBezierPath bezierPathWithArcCenter:self.CGPoinCerter radius:_radius startAngle:self.startAngle endAngle:self.endInnerAngle clockwise:self.clockwise];
    cPath.lineWidth=self.lineWith;
    cPath.lineCapStyle = kCGLineCapRound;
    cPath.lineJoinStyle = kCGLineJoinRound;
    UIColor *color = self.unfillColor;
    [color setStroke];
    [cPath stroke];
    }
    

    用法
    - (void)setCircle{

    ZYCircle *circle = [[ZYCircle alloc] initWithFrame:CGRectMake(30, 20,SCREEN_WIDTH-60 , SCREEN_WIDTH-60)];
    circle.percentage = 0.23;    //百分比数值
    circle.lineWith = 30;       //线宽
    circle.fillColor = [UIColor redColor];          //填充颜色
    circle.unfillColor = [UIColor lightGrayColor];  //未填充颜色
    circle.startAngle = 150;        //百分百的圆环起点
    circle.endInnerAngle = 390;     //百分百的圆环终点
    //  circle.centerLable.text = @"111"; //中心标签的显示数值,默认为百分数
          [self.displayView addSubview:circle];
    
     }
    
    #pragma mark - 点击方法
    - (IBAction)百分比圆环:(id)sender {
    [self setCircle];
     }

    相关文章

      网友评论

      • ChauvetMa:这个例子有个可以优化的地方,当percentage写100时,画出来的是整个圆形,按照理想应该是150-390这段圆弧,原因是你里面绘制的时候,没有做数据合法性校验,percentage应该在0-1之间,若用户填写不合法,应该处理到临界值。
        麦穗0615:北京
        ChauvetMa:@_正阳_ 满大街都是IOS哈,你在哪个城市呢,我在南京
        麦穗0615:@ChauvetMa 👌thanks求工作
      • Berning:这种东西太简单了,不用解读
      • ios肖:可以看看!!

      本文标题:iOS - 关于百分比圆环的解读

      本文链接:https://www.haomeiwen.com/subject/fhyapttx.html