带有 UIBezierPath 的 CAShapeLayer 阴影

CAShapeLayer Shadow with UIBezierPath

这个问题从 继续。

我有以下 CAShapeLayer:

- (CAShapeLayer *)gaugeCircleLayer {

    if (_gaugeCircleLayer == nil) {
        _gaugeCircleLayer = [CAShapeLayer layer];
        _gaugeCircleLayer.lineWidth = self.gaugeWidth;
        _gaugeCircleLayer.fillColor = [UIColor clearColor].CGColor;
        _gaugeCircleLayer.strokeColor = self.gaugeTintColor.CGColor;
        _gaugeCircleLayer.strokeStart = 0.0f;
        _gaugeCircleLayer.strokeEnd = self.value;
        _gaugeCircleLayer.lineCap = kCALineCapRound;
        _gaugeCircleLayer.path = [self insideCirclePath].CGPath;

        CAShapeLayer *cap = [CAShapeLayer layer];
        cap.shadowColor = [UIColor blackColor].CGColor;
        cap.shadowRadius = 8.0;
        cap.shadowOpacity = 0.9;
        cap.shadowOffset = CGSizeMake(0, 0);
        cap.fillColor = [UIColor grayColor].CGColor;
        [_gaugeCircleLayer addSublayer:cap];
    }

    return _gaugeCircleLayer;
}

然后我有以下UIBezierPath

- (UIBezierPath *)insideCirclePath {

    CGPoint arcCenter = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:arcCenter
                                                        radius:CGRectGetWidth(self.bounds) / 2.0f
                                                    startAngle:(3.0f * M_PI_2)
                                                      endAngle:(3.0f * M_PI_2) + (2.0f * M_PI)
                                                     clockwise:YES];


    return path;
}

这会产生如下内容:

我想用 cap 子图层制作的是末尾的投影,我也很想知道如何让 GradientLayer 像下图一样工作:

问题是子层没有出现在任何地方,我不太清楚为什么。我也不是 100% 确定这是否是产生预期效果的最佳方式。

更新:

以下代码 ,但我不太确定如何将其正确添加到我的 UIBezierPath 中:

let cap = CAShapeLayer()
cap.shadowColor = UIColor.blackColor().CGColor
cap.shadowRadius = 8.0
cap.shadowOpacity = 0.9
cap.shadowOffset = CGSize(width: 0, height: 0)
cap.path = UIBezierPath(ovalInRect: CGRectMake(0, 40, 20, 20)).CGPath
cap.fillColor = UIColor.grayColor().CGColor
layer.addSublayer(cap)

这应该可以解决问题。 唯一剩下的问题是动画,帽子没有动画。 诀窍是将上限添加到仪表的末尾,并在仪表的值发生变化时更新它。为了计算位置,使用了一点数学魔法。它需要低于规格,因此在 trackCircleLayer

中添加了上限
//
//  CHCircleGaugeView.m
//
//  Copyright (c) 2014 ChaiOne <http://www.chaione.com/>
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.

#import "CHCircleGaugeView.h"
#import "CHCircleGaugeViewDebugMacros.h"
#import <CoreText/CoreText.h>
#import <QuartzCore/QuartzCore.h>

static CGFloat const CHKeyAnimationDuration = 0.5f;
static CGFloat const CHKeyDefaultValue = 0.0f;
static CGFloat const CHKeyDefaultFontSize = 32.0f;
static CGFloat const CHKeyDefaultTrackWidth = 0.5f;
static CGFloat const CHKeyDefaultGaugeWidth = 2.0f;
static NSString * const CHKeyDefaultNAText = @"n/a";
static NSString * const CHKeyDefaultNoAnswersText = @"%";
#define CHKeyDefaultTrackTintColor [UIColor blackColor]
#define CHKeyDefaultGaugeTintColor [UIColor blackColor]
#define CHKeyDefaultTextColor [UIColor blackColor]

@interface CHCircleGaugeView ()

@property (nonatomic, strong) CAShapeLayer *trackCircleLayer;
@property (nonatomic, strong) CAShapeLayer *gaugeCircleLayer;
// ADDED
@property (nonatomic, strong) CAShapeLayer *capLayer;
// END ADDED
@property (nonatomic, strong) UILabel *valueTextLabel;

@end

@implementation CHCircleGaugeView

#pragma mark - View Initialization

- (instancetype)init {

    return [self initWithFrame:CGRectZero];
}

- (instancetype)initWithFrame:(CGRect)frame {

    self = [super initWithFrame:frame];

    if (self) {

        [self initSetup];
    }

    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {

    self = [super initWithCoder:aDecoder];

    if (self) {

        [self initSetup];
    }

    return self;
}

- (void)initSetup {

    _state = CHCircleGaugeViewStateNA;
    _value = CHKeyDefaultValue;
    _trackTintColor = CHKeyDefaultTrackTintColor;
    _gaugeTintColor = CHKeyDefaultGaugeTintColor;
    _textColor = CHKeyDefaultTextColor;
    _font = [UIFont systemFontOfSize:CHKeyDefaultFontSize];
    _trackWidth = CHKeyDefaultTrackWidth;
    _gaugeWidth = CHKeyDefaultGaugeWidth;
    _notApplicableString = CHKeyDefaultNAText;
    _noDataString = CHKeyDefaultNoAnswersText;
    [self createGauge];
}

- (void)createGauge {

    [self.layer addSublayer:self.trackCircleLayer];
    [self.layer addSublayer:self.gaugeCircleLayer];
    [self addSubview:self.valueTextLabel];

    [self setupConstraints];
}

- (void)setupConstraints {

    NSDictionary *viewDictionary = @{@"valueText" : self.valueTextLabel};
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[valueText]|" options:0 metrics:nil views:viewDictionary]];
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[valueText]|" options:0 metrics:nil views:viewDictionary]];
}

#pragma mark - Property Setters

- (void)setState:(CHCircleGaugeViewState)state {

    if (_state != state) {

        _state = state;

        switch (state) {
            case CHCircleGaugeViewStateNA: {
                [self updateGaugeWithValue:0 animated:NO];

                break;
            }
            case CHCircleGaugeViewStatePercentSign: {
                [self updateGaugeWithValue:0 animated:NO];

                break;
            }
            case CHCircleGaugeViewStateScore: {
                [self updateGaugeWithValue:self.value animated:NO];

                break;
            }

            default: {
                ALog(@"Missing gauge state.");

                break;
            }
        }
    }
}

- (void)setValue:(CGFloat)value {

    [self setValue:value animated:NO];
}

- (void)setValue:(CGFloat)value animated:(BOOL)animated {

    self.state = CHCircleGaugeViewStateScore;

    if (value != _value) {

        [self willChangeValueForKey:NSStringFromSelector(@selector(value))];
        value = MIN(1.0f, MAX(0.0f, value));
        [self updateGaugeWithValue:value animated:animated];
        _value = value;
        [self didChangeValueForKey:NSStringFromSelector(@selector(value))];
    }
}

- (void)setUnitsString:(NSString *)unitsString {

    if ([_unitsString isEqualToString:unitsString] == NO) {
        _unitsString = [unitsString copy];
        self.valueTextLabel.attributedText = [self formattedStringForValue:self.value];
    }
}

- (void)updateGaugeWithValue:(CGFloat)value animated:(BOOL)animated {

    self.valueTextLabel.attributedText = [self formattedStringForValue:value];

    BOOL previousDisableActionsValue = [CATransaction disableActions];
    [CATransaction setDisableActions:YES];
    self.gaugeCircleLayer.strokeEnd = value;

    // ADDED
    _capLayer.path = [self capPathForValue:value].CGPath;
    // END ADDED

    if (animated) {

        self.gaugeCircleLayer.strokeEnd = value;
        CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
        pathAnimation.duration = CHKeyAnimationDuration;
        pathAnimation.fromValue = [NSNumber numberWithFloat:self.value];
        pathAnimation.toValue = [NSNumber numberWithFloat:value];
        pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        [self.gaugeCircleLayer addAnimation:pathAnimation forKey:@"strokeEndAnimation"];
    }

    [CATransaction setDisableActions:previousDisableActionsValue];
}

- (void)setTrackTintColor:(UIColor *)trackTintColor {

    if (_trackTintColor != trackTintColor) {

        _trackTintColor = trackTintColor;
        self.trackCircleLayer.strokeColor = trackTintColor.CGColor;
    }
}

- (void)setGaugeTintColor:(UIColor *)gaugeTintColor {

    if (_gaugeTintColor != gaugeTintColor) {

        _gaugeTintColor = gaugeTintColor;
        self.gaugeCircleLayer.strokeColor = gaugeTintColor.CGColor;

        // ADDED
        self.capLayer.fillColor = gaugeTintColor.CGColor;
        // END ADDED
    }
}

- (void)setTrackWidth:(CGFloat)trackWidth {

    if (_trackWidth != trackWidth) {

        _trackWidth = trackWidth;
        self.trackCircleLayer.lineWidth = trackWidth;
        [self.layer layoutSublayers];
    }
}

- (void)setGaugeWidth:(CGFloat)gaugeWidth {

    if (_gaugeWidth != gaugeWidth) {

        _gaugeWidth = gaugeWidth;
        self.gaugeCircleLayer.lineWidth = gaugeWidth;
        [self.layer layoutSublayers];
    }
}

- (void)setTextColor:(UIColor *)textColor {

    if (_textColor != textColor) {

        _textColor = textColor;
        self.valueTextLabel.textColor = textColor;
    }
}

- (void)setFont:(UIFont *)font {

    if (_font != font) {

        _font = font;
        self.valueTextLabel.font = font;
    }
}

- (void)setGaugeStyle:(CHCircleGaugeStyle)gaugeStyle {

    if (_gaugeStyle != gaugeStyle) {
        _gaugeStyle = gaugeStyle;
        [self.layer layoutSublayers];
    }
}

#pragma mark - Circle Shapes

- (CAShapeLayer *)trackCircleLayer {

    if (_trackCircleLayer == nil) {

        _trackCircleLayer = [CAShapeLayer layer];
        _trackCircleLayer.lineWidth = self.trackWidth;
        _trackCircleLayer.fillColor = [UIColor clearColor].CGColor;
        _trackCircleLayer.strokeColor = self.trackTintColor.CGColor;
        _trackCircleLayer.path = [self insideCirclePath].CGPath;

        // ADDED
        _capLayer = [CAShapeLayer layer];
        _capLayer.shadowColor = [UIColor blackColor].CGColor;
        _capLayer.shadowRadius = 8.0;
        _capLayer.shadowOpacity = 0.9;
        _capLayer.shadowOffset = CGSizeMake(0, 0);
        _capLayer.fillColor = self.gaugeTintColor.CGColor;
        _capLayer.path = [self capPathForValue:self.value].CGPath;
        [_trackCircleLayer addSublayer:_capLayer];
        // END ADDED
    }

    return _trackCircleLayer;
}

- (CAShapeLayer *)gaugeCircleLayer {

    if (_gaugeCircleLayer == nil) {

        _gaugeCircleLayer = [CAShapeLayer layer];
        _gaugeCircleLayer.lineWidth = self.gaugeWidth;
        _gaugeCircleLayer.fillColor = [UIColor clearColor].CGColor;
        _gaugeCircleLayer.strokeColor = self.gaugeTintColor.CGColor;
        _gaugeCircleLayer.strokeStart = 0.0f;
        _gaugeCircleLayer.strokeEnd = self.value;
        _gaugeCircleLayer.path = [self circlPathForCurrentGaugeStyle].CGPath;
    }

    return _gaugeCircleLayer;
}

// ADDED
- (UIBezierPath *)capPathForValue:(float)value {
    CGPoint arcCenter = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
    CGFloat radius = CGRectGetWidth(self.bounds) / 2.0f;
    float angle = value * 360.0;
    float x = radius * sin(angle*M_PI/180.0);
    float y = radius * cos(angle*M_PI/180.0);

    CGPoint capArcCenter = CGPointMake(arcCenter.x + x, arcCenter.y - y);
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:capArcCenter
                                                        radius:self.gaugeWidth*_capLayer.shadowRadius / 2.0f
                                                    startAngle:(3.0f * M_PI_2)
                                                      endAngle:(3.0f * M_PI_2) + (2.0f * M_PI)
                                                     clockwise:YES];
    return path;
}
// END ADDED

- (UIBezierPath *)circlPathForCurrentGaugeStyle {

    switch (self.gaugeStyle) {
        case CHCircleGaugeStyleInside: {
            return [self insideCirclePath];
        }
        case CHCircleGaugeStyleOutside: {
            return [self outsideCirclePath];
        }
        default: {
            return nil;
        }
    }
}

- (UIBezierPath *)insideCirclePath {

    CGPoint arcCenter = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:arcCenter
                                                        radius:CGRectGetWidth(self.bounds) / 2.0f
                                                    startAngle:(3.0f * M_PI_2)
                                                      endAngle:(3.0f * M_PI_2) + (2.0f * M_PI)
                                                     clockwise:YES];

    return path;
}

- (UIBezierPath *)outsideCirclePath {

    CGPoint arcCenter = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
    CGFloat radius = (CGRectGetWidth(self.bounds) / 2.0f) + (self.trackWidth / 2.0f) + (self.gaugeWidth / 2.0f);
    UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:arcCenter
                                                        radius:radius
                                                    startAngle:(3.0f * M_PI_2)
                                                      endAngle:(3.0f * M_PI_2) + (2.0f * M_PI)
                                                     clockwise:YES];

    return path;
}

#pragma mark - Text Label

- (UILabel *)valueTextLabel {

    if (_valueTextLabel == nil) {

        _valueTextLabel = [[UILabel alloc] init];
        [_valueTextLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
        _valueTextLabel.textAlignment = NSTextAlignmentCenter;
        _valueTextLabel.attributedText = [self formattedStringForValue:self.value];
    }

    return _valueTextLabel;
}

- (NSAttributedString *)formattedStringForValue:(CGFloat)value {

    NSAttributedString *valueString;
    NSDictionary *stringAttributes = @{
                                       NSForegroundColorAttributeName : self.textColor,
                                       NSFontAttributeName : self.font
                                       };

    switch (self.state) {
        case CHCircleGaugeViewStateNA: {
            valueString = [[NSAttributedString alloc] initWithString:self.notApplicableString attributes:stringAttributes];

            break;
        }
        case CHCircleGaugeViewStatePercentSign: {
            valueString = [[NSAttributedString alloc] initWithString:self.noDataString attributes:stringAttributes];

            break;
        }
        case CHCircleGaugeViewStateScore: {
            NSString *suffix = self.unitsString ? self.unitsString : @"";
            valueString = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%.0f %@", value * 100.0f, suffix]
                                                          attributes:stringAttributes];

            break;
        }

        default: {
            ALog(@"Missing gauge state.");

            break;
        }
    }

    return valueString;
}

#pragma mark - KVO

// Handling KVO notifications for the value property, since
//   we're proxying with the setValue:animated: method.
+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key {

    if ([key isEqualToString:NSStringFromSelector(@selector(value))]) {

        return NO;
    } else {

        return [super automaticallyNotifiesObserversForKey:key];
    }
}

#pragma mark - CALayerDelegate

- (void)layoutSublayersOfLayer:(CALayer *)layer {

    [super layoutSublayersOfLayer:layer];

    if (layer == self.layer) {

        self.trackCircleLayer.path = [self insideCirclePath].CGPath;
        self.gaugeCircleLayer.path = [self circlPathForCurrentGaugeStyle].CGPath;
    }
}

@end

我不知道这对您是否有用,因为它不使用 CHCircleGaugeView。我正在处理与这个问题相关的几个项目,所以我将它们混合在一起并进行了一些更改以生成一个进度视图,该视图具有颜色渐变背景,其尖端与末端 100% 重叠。我还没有达到让圆形尖端在 0% 时消失的地步,但我最终会到达那里。以下是在 2 个不同的进度级别上对它的一些看法,

视图是使用在 drawRect 中绘制的极坐标渐变创建的,由圆环遮盖。圆形尖端是一个单独的层,它是连接到圆心的直线末端的半圆,圆心围绕其中心旋转,并根据进度水平进行变换。这是代码,

    @implementation AnnulusProgressView{ // subclass of UIView
    int slices;
    CGFloat circleRadius;
    CAShapeLayer *maskLayer;
    CGFloat segmentAngle;
    CGFloat startAngle;
    CAShapeLayer *tipView;
    NSMutableArray *colors;
    int sign;
}


-(instancetype)initWithFrame:(CGRect)frame wantsBackgroundRing:(BOOL)wantsBackground backgroundRingColor:(UIColor *)ringColor {
    if (self = [super initWithFrame:frame]) {
        slices = 360;
        _ringThickness = 12;
        circleRadius = self.bounds.size.width/2;
        _startColor = [UIColor colorWithHue:0.24 saturation:1 brightness:0.8 alpha:1];
        _endColor = [UIColor colorWithHue:0.03 saturation:1 brightness:1 alpha:1];
        [self setupColorArray];
        _backgroundRing = wantsBackground? [self createBackgroundRingWithColor:ringColor] : nil;
        self.layer.mask = [self createAnnulusMask];
    }
    return self;
}


-(void)setStartColor:(UIColor *)startColor {
    _startColor = startColor;
    [self setupColorArray];
}


-(void)setEndColor:(UIColor *)endColor {
    _endColor = endColor;
    [self setupColorArray];
}


-(void)setupColorArray {
    colors = [NSMutableArray new];
    CGFloat startHue, startSaturation, startBrightness, startAlpha, endHue, endSaturation, endBrightness, endAlpha;

    [self.startColor getHue:&startHue saturation:&startSaturation brightness:&startBrightness alpha:&startAlpha];
    [self.endColor getHue:&endHue saturation:&endSaturation brightness:&endBrightness alpha:&endAlpha];

    for(int i=0;i<slices;i++){
        CGFloat hue = startHue + (endHue - startHue)*i/slices;
        CGFloat brightness = startBrightness + (endBrightness - startBrightness)*i/slices;
        CGFloat saturation = startSaturation + (endSaturation - startSaturation)*i/slices;
        CGFloat alpha = startAlpha + (endAlpha - startAlpha)*i/slices;
        UIColor *color = [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:alpha];
        [colors addObject:color];
    }
    self.progress = _progress;
}



-(UIView *)createBackgroundRingWithColor:(UIColor *) color {
    UIView *bgRing = [[UIView alloc] initWithFrame:self.frame];
    bgRing.backgroundColor = color;
    bgRing.layer.mask = [self createAnnulusMask];
    [(CAShapeLayer *)bgRing.layer.mask setStrokeEnd:startAngle + 2*M_PI ];
    return bgRing;
}



-(void)didMoveToSuperview {
    if (self.backgroundRing) [self.superview insertSubview:self.backgroundRing belowSubview:self];
    tipView = [self tipView];
    [self.superview.layer addSublayer:tipView];
}



-(CAShapeLayer *)tipView {
    CAShapeLayer *tip = [CAShapeLayer layer];
    tip.frame = self.frame;
    tip.fillColor = [UIColor redColor].CGColor;
    UIBezierPath *shape = [UIBezierPath bezierPath];
    CGPoint center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
    [shape moveToPoint:center];
    CGPoint bottomPoint = CGPointMake(center.x, center.y + circleRadius - self.ringThickness*2);
    CGFloat tipCenterY = bottomPoint.y + self.ringThickness - 1;
    [shape addLineToPoint: bottomPoint];
    [shape addLineToPoint:CGPointMake(bottomPoint.x+2, bottomPoint.y)];
    double fractionAlongTangent = self.ringThickness;
    [shape addCurveToPoint:CGPointMake(center.x, center.y + circleRadius) controlPoint1:CGPointMake(center.x - self.ringThickness*1.5, tipCenterY - fractionAlongTangent) controlPoint2:CGPointMake(center.x - self.ringThickness*1.5, tipCenterY + fractionAlongTangent)];
    [shape closePath];
    tip.path = shape.CGPath;
    tip.shadowColor = [UIColor darkGrayColor].CGColor;
    tip.shadowOpacity = 0.8;
    tip.shadowOffset = CGSizeMake(-6, 0);
    tip.shadowRadius = 2;
    return tip;
}



- (void)setProgress:(CGFloat)progress{
    sign = (progress >= _progress)? 1 : -1;
    [self animateProgressTo:@(progress)];
}


-(void)animateProgressTo:(NSNumber *) newValueNumber{
    float newValue = newValueNumber.floatValue;
    _progress =  (_progress + (sign * 0.1) > 1)?  1 : _progress + (sign * 0.1);
    if ((_progress > newValue && sign == 1) || (_progress < newValue && sign == -1)) {
        _progress = newValue;
    }
    maskLayer.strokeEnd = _progress;
    tipView.transform =  CATransform3DMakeRotation(-(1 - _progress + 0.002) * M_PI*2, 0, 0, 1); //the 0.002 closes a small gap between the tip and the annulus strokeEnd
    int i = (int)(_progress*(slices - 1));
    tipView.fillColor = ((UIColor *)colors[i]).CGColor;
    if (sign == 1) {
        if (_progress < newValue) {
            [self performSelector:@selector(animateProgressTo:) withObject:@(newValue) afterDelay:0.05];
        }
    }else{
        if (_progress > newValue) {
            [self performSelector:@selector(animateProgressTo:) withObject:@(newValue) afterDelay:0.05];
        }
    }

    NSLog(@"%f",_progress);
}



- (CAShapeLayer *)createAnnulusMask {
    maskLayer = [CAShapeLayer layer];
    maskLayer.frame = self.bounds;

    segmentAngle = 2*M_PI/(slices);
    startAngle = M_PI_2;
    CGFloat endAngle = startAngle + 2*M_PI;

    maskLayer.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)) radius:circleRadius - self.ringThickness startAngle:startAngle  endAngle:endAngle clockwise:YES].CGPath;
    maskLayer.fillColor = [UIColor clearColor].CGColor;
    maskLayer.strokeColor = [UIColor blackColor].CGColor;
    maskLayer.lineWidth = self.ringThickness * 2;
    maskLayer.strokeEnd = self.progress;
    return  maskLayer;
}



-(void)drawRect:(CGRect)rect{
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSetAllowsAntialiasing(ctx, NO);
    CGPoint center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));

    for(int i=0;i<slices;i++){
        CGContextSaveGState(ctx);
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path moveToPoint:center];
        [path addArcWithCenter:center radius:circleRadius startAngle:startAngle endAngle:startAngle+segmentAngle clockwise:YES];
        [path addClip];
        [colors[i] setFill];
        [path fill];
        CGContextRestoreGState(ctx);

        startAngle += segmentAngle;
    }
}