圆形进度条,可设置内外环,多彩

今天做一个健身的项目,客户需要一个圆形的进度条来查看个人的运动记录等,做了一些功课之后贴出代码大家一起分享下


代码比较长,多,在这里我先放上demo下载地址  http://download.csdn.net/detail/a174455171/9517479

新建一个继承UIView类

.h文件

@interface MyProgressView : UIView


@property (strong,nonatomic)UILabel *textLabel;



@property (nonatomic)double progress;


@property (nonatomic)NSInteger showTextUI_APPEARANCE_SELECTOR;

@property (nonatomic)NSInteger roundedHeadUI_APPEARANCE_SELECTOR;

@property (nonatomic)NSInteger showShadowUI_APPEARANCE_SELECTOR;


@property (nonatomic)CGFloat thicknessRatioUI_APPEARANCE_SELECTOR;


/**

 *  设置内环和外环时使用

 */

@property (nonatomic,strong) UIColor *innerBackgroundColorUI_APPEARANCE_SELECTOR;

@property (nonatomic,strong) UIColor *outerBackgroundColorUI_APPEARANCE_SELECTOR;


@property (nonatomic,strong) UIFont *fontUI_APPEARANCE_SELECTOR;


/**

 *  只有一种颜色时使用

 */

@property (nonatomic,strong) UIColor *progressFillColorUI_APPEARANCE_SELECTOR;


@property (nonatomic,strong) UIColor *progressTopGradientColorUI_APPEARANCE_SELECTOR;

@property (nonatomic,strong) UIColor *progressBottomGradientColorUI_APPEARANCE_SELECTOR;


@property (strong,nonatomic)NSArray *colorArray;       //多彩时使用

@property (strong,nonatomic)NSArray *shadeArray;       //每个颜色处于的位置

@property (nonatomic,readonly)CGFloat *back;


/**

 *  设置多彩圆环

 *

 *  @param colorArray 颜色数组

 *  @param shadeArray 每个颜色处于的位置

 */

-(void)setColorArray:(NSArray *)colorArray shadeArray:(NSArray *)shadeArray;


.m文件

#import <math.h>


#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)


@interface MyProgressView ()


@property (nonatomic)UIBezierPath *path;

@property (nonatomic)CAShapeLayer *shapeLayer;

@property (nonatomic)UIBezierPath *path1;

@property (nonatomic)CAShapeLayer *shapeLayer1;


@property (strong,nonatomic)UIImageView *imageView;






@end


@implementation MyProgressView


+ (void)initialize

{

    if (self == [MyProgressViewclass])

    {

        id appearance = [selfappearance];

        

        [appearance setShowText:NO];//用来控制是否显示显示label

        [appearance setRoundedHead:YES];//用来控制是否对进度两边进行处理

        [appearance setShowShadow:YES];//控制圆环进度条的样式

        

        [appearance setThicknessRatio:0.1f];//圆环进度条的宽度

        

        [appearance setInnerBackgroundColor:nil];

        [appearance setOuterBackgroundColor:nil];

        

//        [appearance setProgressFillColor:[UIColor redColor]];//整个进度条颜色

//        [appearance setProgressTopGradientColor:[UIColor greenColor]];//进度条前半部分颜色

//        [appearance setProgressBottomGradientColor:[UIColor redColor]];//进度条后半部分颜色

        [appearance setBackgroundColor:[UIColorclearColor]];

    }

}


- (void)drawRect:(CGRect)rect

{

    // Calculate position of the circle

    CGFloat progressAngle = _progress * 360.0 - 90;

    CGPoint center = CGPointMake(rect.size.width /2.0f, rect.size.height /2.0f);

    CGFloat radius = MIN(rect.size.width, rect.size.height) /2.0f;

    

    CGRect square;

    if (rect.size.width > rect.size.height)

    {

        square = CGRectMake((rect.size.width - rect.size.height) /2.0, 0.0, rect.size.height, rect.size.height);

    }

    else

    {

        square = CGRectMake(0.0, (rect.size.height - rect.size.width) / 2.0, rect.size.width, rect.size.width);

    }

    

    //进度条宽度

    CGFloat circleWidth = radius * _thicknessRatio;

    CGContextRef context =UIGraphicsGetCurrentContext();

    CGContextSaveGState(context);

    

    if (_innerBackgroundColor)

    {

        //内环

        // Fill innerCircle with innerBackgroundColor

        UIBezierPath *innerCircle = [UIBezierPathbezierPathWithArcCenter:center

                                                                   radius:radius - circleWidth

                                                               startAngle:2*M_PI

                                                                 endAngle:0.0

                                                                clockwise:YES];

        

        [_innerBackgroundColorsetFill];

        

        [innerCircle fill];

    }

    

    if (_outerBackgroundColor)

    {

        //外环

        // Fill outerCircle with outerBackgroundColor

        UIBezierPath *outerCircle = [UIBezierPathbezierPathWithArcCenter:center

                                                                   radius:radius

                                                               startAngle:0.0

                                                                 endAngle:2*M_PI

                                                                clockwise:NO];

        [outerCircle addArcWithCenter:center

                               radius:radius - circleWidth

                           startAngle:2*M_PI

                             endAngle:0.0

                            clockwise:YES];

        

        [_outerBackgroundColorsetFill];

        

        [outerCircle fill];

    }

    

    if (_showShadow)

    {

        //圆环背景处理

        CGFloat locations[5] = {0.0f, 0.33f,0.66f, 1.0f };

//                NSArray *gradientColors = @[

//                                            (id)[[UIColor colorWithWhite:0.3 alpha:0.5] CGColor],

//                                            (id)[[UIColor colorWithWhite:0.9 alpha:0.0] CGColor],

//                                            (id)[[UIColor colorWithWhite:0.9 alpha:0.0] CGColor],

//                                            (id)[[UIColor colorWithWhite:0.3 alpha:0.5] CGColor],

//                                            ];

        

        NSArray *gradientColors = @[

                                    (id)[[UIColorcolorWithWhite:0.7alpha:1] CGColor],

                                    (id)[[UIColorcolorWithWhite:0.7alpha:1] CGColor],

                                    (id)[[UIColorcolorWithWhite:0.7alpha:1] CGColor],

                                    (id)[[UIColorcolorWithWhite:0.7alpha:1] CGColor],

                                    ];

        

        CGColorSpaceRef rgb =CGColorSpaceCreateDeviceRGB();

        CGGradientRef gradient = CGGradientCreateWithColors(rgb, (__bridgeCFArrayRef)gradientColors, locations);

        CGContextDrawRadialGradient(context, gradient, center, radius - circleWidth, center, radius,0);

        CGGradientRelease(gradient);

        CGColorSpaceRelease(rgb);

    }

    

    if (_showText)

    {

        if (!_progress) {

            return;

        }

        if ([selfviewWithTag:5]) {

            [_textLabelremoveFromSuperview];

        }

        //中间显示label

        _textLabel = [[UILabelalloc] init];

        //字符串处理

        NSString *str = [NSStringstringWithFormat:@"%0.2f%%\n收益率",_progress * 100.0];

        NSMutableAttributedString *progressStr = [[NSMutableAttributedStringalloc] initWithString:str];

        //6位字符 颜色

        [progressStr addAttribute:NSForegroundColorAttributeNamevalue:[UIColorredColor] range:NSMakeRange(0,6)];

        //第七位向后的3个字符颜色

        [progressStr addAttribute:NSForegroundColorAttributeNamevalue:[UIColorblackColor] range:NSMakeRange(7,3)];

        [progressStr addAttribute:NSFontAttributeNamevalue:[UIFontboldSystemFontOfSize:16.0]range:NSMakeRange(0,6)];

        [progressStr addAttribute:NSFontAttributeNamevalue:[UIFontsystemFontOfSize:13]range:NSMakeRange(7,3)];

        _textLabel.attributedText = progressStr;

        _textLabel.numberOfLines =0;

        _textLabel.bounds =CGRectMake(0,0, 100, 50);

        _textLabel.center =CGPointMake(self.bounds.size.width/2.0,self.bounds.size.height/2.0);

        _textLabel.tag =5;

        _textLabel.textAlignment =NSTextAlignmentCenter;

        [self addSubview:_textLabel];

        

    }

    

    UIBezierPath *path = [UIBezierPathbezierPath];

    

    

    [path appendPath:[UIBezierPathbezierPathWithArcCenter:center

                                                    radius:radius

                                                startAngle:DEGREES_TO_RADIANS(-90)

                                                  endAngle:DEGREES_TO_RADIANS(progressAngle)

                                                 clockwise:YES]];

    

    if (_roundedHead)

    {

        //终点处理  也可以给终点放置一些图片等

        CGPoint point;

        point.x = (cos(DEGREES_TO_RADIANS(progressAngle)) * (radius - circleWidth/2)) + center.x;

        point.y = (sin(DEGREES_TO_RADIANS(progressAngle)) * (radius - circleWidth/2)) + center.y;

        

        [path addArcWithCenter:point

                        radius:circleWidth/2

                    startAngle:DEGREES_TO_RADIANS(progressAngle)

                      endAngle:DEGREES_TO_RADIANS(270.0 + progressAngle -90.0)

                     clockwise:YES];

    }

    

    [path addArcWithCenter:center

                    radius:radius-circleWidth

                startAngle:DEGREES_TO_RADIANS(progressAngle)

                  endAngle:DEGREES_TO_RADIANS(-90)

                 clockwise:NO];

    //起始点添加分割线

//    UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(radius, 0, 1, circleWidth)];

//    lineView.backgroundColor = [UIColor whiteColor];

//    [self addSubview:lineView];

    

    if (_roundedHead)

    {

        //起始点处理

        //        CGPoint point;

        //        point.x = (cos(DEGREES_TO_RADIANS(-90)) * (radius - circleWidth/2)) + center.x;

        //        point.y = (sin(DEGREES_TO_RADIANS(-90)) * (radius - circleWidth/2)) + center.y;

        //

        //        [path addArcWithCenter:point

        //                        radius:circleWidth/2

        //                    startAngle:DEGREES_TO_RADIANS(90)

        //                      endAngle:DEGREES_TO_RADIANS(-90)

        //                     clockwise:NO];

    }

    

    [path closePath];

    //进度条颜色处理

    if (_progressFillColor)

    {

        [_progressFillColorsetFill];

        [path fill];

    }

    elseif (_progressTopGradientColor &&_progressBottomGradientColor)

    {

        [path addClip];

        

        NSArray *backgroundColors = @[

                                      (id)[_progressTopGradientColorCGColor],

                                      (id)[_progressBottomGradientColorCGColor],

                                      ];

        

        CGFloat backgroudColorLocations[2] = {0.0f,1.0f};

        

        CGColorSpaceRef rgb =CGColorSpaceCreateDeviceRGB();

        CGGradientRef backgroundGradient = CGGradientCreateWithColors(rgb, (__bridgeCFArrayRef)(backgroundColors), backgroudColorLocations);

        CGContextDrawLinearGradient(context,

                                    backgroundGradient,

                                    CGPointMake(0.0f, square.origin.y),

                                    CGPointMake(0.0f, square.size.height),

                                    0);

        CGGradientRelease(backgroundGradient);

        CGColorSpaceRelease(rgb);

    }

    else

    {

        [path addClip];

        

        NSMutableArray *backgroundColors = [[NSMutableArrayalloc] init];

        for (UIColor *colorin _colorArray)

        {

            [backgroundColors addObject:(id)[colorCGColor]];

        }

        CGColorSpaceRef rgb =CGColorSpaceCreateDeviceRGB();

        CGGradientRef backgroundGradient = CGGradientCreateWithColors(rgb, (__bridgeCFArrayRef)(backgroundColors), _back);

        CGContextDrawLinearGradient(context,

                                    backgroundGradient,

                                    CGPointMake(0.0f, square.origin.y),

                                    CGPointMake(0.0f, square.size.height),

                                    0);

        CGGradientRelease(backgroundGradient);

        CGColorSpaceRelease(rgb);

    }

    CGContextRestoreGState(context);

}


#pragma mark - Setter

//设置进度

- (void)setProgress:(double)progress

{

    _progress = MIN(1.0,MAX(0.0, progress));

    

    [selfsetNeedsDisplay];

}


#pragma mark - UIAppearance


- (void)setShowText:(NSInteger)showText

{

    _showText = showText;

    

    [selfsetNeedsDisplay];

}


- (void)setRoundedHead:(NSInteger)roundedHead

{

    _roundedHead = roundedHead;

    

    [selfsetNeedsDisplay];

}


- (void)setShowShadow:(NSInteger)showShadow

{

    _showShadow = showShadow;

    

    [selfsetNeedsDisplay];

}

//进度条宽度与半径之比

- (void)setThicknessRatio:(CGFloat)thickness

{

    _thicknessRatio = MIN(MAX(0.0f, thickness),1.0f);

    

    [selfsetNeedsDisplay];

}

//内环

- (void)setInnerBackgroundColor:(UIColor *)innerBackgroundColor

{

    _innerBackgroundColor = innerBackgroundColor;

    

    [selfsetNeedsDisplay];

}

//外环

- (void)setOuterBackgroundColor:(UIColor *)outerBackgroundColor

{

    _outerBackgroundColor = outerBackgroundColor;

    

    [selfsetNeedsDisplay];

}

//进度条颜色

- (void)setProgressFillColor:(UIColor *)progressFillColor

{

    _progressFillColor = progressFillColor;

    

    [selfsetNeedsDisplay];

}

//进度条前半部分颜色

- (void)setProgressTopGradientColor:(UIColor *)progressTopGradientColor

{

    _progressTopGradientColor = progressTopGradientColor;

    

    [selfsetNeedsDisplay];

}

//进度条后半部分颜色

- (void)setProgressBottomGradientColor:(UIColor *)progressBottomGradientColor

{

    _progressBottomGradientColor = progressBottomGradientColor;

    

    [selfsetNeedsDisplay];

}


-(void)setColorArray:(NSArray *)colorArray

{

    _colorArray = colorArray;

    

    [selfsetNeedsDisplay];

}


-(void)setShadeArray:(NSArray *)shadeArray

{

    _shadeArray = shadeArray;

    

    [selfsetNeedsDisplay];

}


-(void)setColorArray:(NSArray *)colorArray shadeArray:(NSArray *)shadeArray

{

    _colorArray = colorArray;

    _shadeArray = shadeArray;

    _back = (CGFloat *)malloc(shadeArray.count*sizeof(CGFloat));

    for (int i=0; i<shadeArray.count; i++)

    {

        _back[i] = [_shadeArray[i]floatValue];

    }

    [selfsetNeedsDisplay];

}


其中有时候会碰到一些需要一个小点或者在进度终点做一些处理,代码里面都有说明


  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
如果您想将 cc.ProgressTimer 圆形进度条设置为一般游戏中的 loading 转动方式,您可以使用 Cocos Creator 中自带的 cc.SpriteAtlas 和 cc.Animation 组件来实现。 具体步骤如下: 1. 创建 cc.SpriteAtlas 资源,并导入多张图片作为动画帧。 2. 在 cc.Animation 组件中创建动画,并将 cc.SpriteAtlas 中的图片添加为动画帧。 3. 在 cc.Animation 组件中设置动画属性,使其循播放,帧率适当等。 4. 在 cc.ProgressTimer 组件中设置 spriteFrame 属性,将其设置为 cc.SpriteAtlas 中的任意一张图片。 5. 在 cc.ProgressTimer 组件中通过 setReverseDirection() 方法将进度条反向,使其从 100% 到 0% 逐渐减少。 6. 在 cc.ProgressTimer 组件中通过 setMode() 方法将进度条设置为 cc.ProgressTimer.Mode.BAR,以使其呈现出圆形进度条的效果。 7. 在 cc.ProgressTimer 组件中通过 setType() 方法将进度条设置为 cc.ProgressTimer.Type.RADIAL,以使其呈现出圆形进度条的效果。 8. 在 cc.ProgressTimer 组件中通过 setBarChangeRate() 方法设置进度条的改变率,使其只在 y 轴方向上变化,以呈现出圆形进度条的效果。 9. 在 cc.ProgressTimer 组件中使用 cc.Animation 组件中创建的动画,通过 runAction() 方法使进度条动起来,呈现出 loading 转动的效果。 以上就是将 cc.ProgressTimer 圆形进度条设置为一般游戏中的 loading 转动方式的步骤,希望对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值