iOS-弧形漸變進(jìn)度條

弧形漸變效果圖

IMG_0114.PNG-w150

CAShapeLayer

基本屬性設(shè)置

CAShapeLayer *shapeLayer = [CAShapeLayer layer];
        shapeLayer.path = [UIBezierPath
                           bezierPathWithArcCenter:CGPointMake(self.frame.size.width * 0.5, self.frame.size.height * 0.5 + 110)
                           radius:120
                           startAngle:(150.f * M_PI) / 180.f
                           endAngle:(390.f * M_PI) / 180.f
                           clockwise:1].CGPath;
        shapeLayer.fillColor = [UIColor clearColor].CGColor;
        shapeLayer.strokeColor = [UIColor lightGrayColor].CGColor;
        shapeLayer.lineWidth = 15.f;
        shapeLayer.lineCap = kCALineCapRound;
        shapeLayer.opacity = 0.8;

屬性介紹

strokeStart屬性和strokeEnd屬性

strokeStart和strokeEnd 是一個(gè)0-1的取值范圍。表示一段路徑的開(kāi)始和結(jié)尾。比如開(kāi)始位置為0.5,結(jié)束位置為1 ,那就只渲染出后半段的路徑。
strokeStart 翻譯過(guò)來(lái)就是清除開(kāi)始位置。
strokeEnd 意思就是清除結(jié)束的位置。

  • keyPath = strokeStart 動(dòng)畫(huà)的fromValue = 0,toValue = 1:
    表示從路徑的0位置畫(huà)到1 怎么畫(huà)是按照清除開(kāi)始的位置也就是清除0 一直清除到1 效果就是一條路徑慢慢的消失。
  • keyPath = strokeStart 動(dòng)畫(huà)的fromValue = 1,toValue = 0:
    表示從路徑的1位置畫(huà)到0 怎么畫(huà)是按照清除開(kāi)始的位置也就是1 這樣開(kāi)始的路徑是空的(即都被清除掉了)一直清除到0 效果就是一條路徑被反方向畫(huà)出來(lái)。
  • keyPath = strokeEnd 動(dòng)畫(huà)的fromValue = 0,toValue = 1:
    表示 這里我們分3個(gè)點(diǎn)說(shuō)明動(dòng)畫(huà)的順序 strokeEnd從結(jié)尾開(kāi)始清除 首先整條路徑先清除后2/3,接著清除1/3 效果就是正方向畫(huà)出路徑。
  • keyPath = strokeEnd 動(dòng)畫(huà)的fromValue = 1,toValue = 0:
    效果就是反方向路徑慢慢消失。

那么我們就可以利用strokeStart和strokeEnd這兩個(gè)屬性,對(duì)CAShapeLayer進(jìn)行添加動(dòng)畫(huà),在設(shè)置percent時(shí),進(jìn)度條就會(huì)出現(xiàn)增大,和減少的兩種動(dòng)態(tài)效果。

- (void)setPercent:(CGFloat)percent {
    _shapeLayer.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.frame.size.width * 0.5, self.frame.size.height * 0.5 + 110) radius:120 startAngle:(150.f * M_PI) / 180.f endAngle:((240.f * (percent - 150.f) / 800.f + 150.f) * M_PI) / 180.f clockwise:1].CGPath;
    CGFloat value = (percent - 150.f) / 800.f;   //計(jì)算進(jìn)度條的位置點(diǎn)
    _shapeLayer.strokeStart = MIN(0, value);
    _shapeLayer.strokeEnd = MAX(0, value);
}

CAGradientLayer

基本屬性設(shè)置,并給CAShapeLayer添加漸變色。做成的整體的進(jìn)度條效果。

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        CAShapeLayer *shapeLayer = [CAShapeLayer layer];
        shapeLayer.path = [UIBezierPath
                           bezierPathWithArcCenter:CGPointMake(self.frame.size.width * 0.5, self.frame.size.height * 0.5 + 110)
                           radius:120
                           startAngle:(150.f * M_PI) / 180.f
                           endAngle:(390.f * M_PI) / 180.f
                           clockwise:1].CGPath;
        shapeLayer.fillColor = [UIColor clearColor].CGColor;
        shapeLayer.strokeColor = [UIColor lightGrayColor].CGColor;
        shapeLayer.lineWidth = 15.f;
        shapeLayer.lineCap = kCALineCapRound;
        shapeLayer.opacity = 0.8;
        _shapeLayer = shapeLayer;
        //上方層
        CAGradientLayer *gradientLayer1 = [CAGradientLayer layer];
        gradientLayer1.frame = self.frame;
        gradientLayer1.colors = self.colorsTop;
        gradientLayer1.startPoint = CGPointMake(0, 0);
        gradientLayer1.endPoint = CGPointMake(1, 0);
        gradientLayer1.mask = shapeLayer;
        
        //左下層
        CAGradientLayer *gradientLayer2 = [CAGradientLayer layer];
        gradientLayer2.frame = CGRectMake(0, SHEIGHT / 2.f + circleRadius / 3.f , SWIDTH / 2, circleRadius * 1.3);
        gradientLayer2.colors = self.colorsLeftBottom;
        gradientLayer2.startPoint = CGPointMake(0, 1);
        gradientLayer2.endPoint = CGPointMake(0, 0);
        
        //右下層
        CAGradientLayer *gradientLayer3 = [CAGradientLayer layer];
        gradientLayer3.frame = CGRectMake(SWIDTH / 2, SHEIGHT / 2.f + circleRadius / 3.f , SWIDTH / 2, circleRadius * 1.3);
        gradientLayer3.colors = self.colorsRightBottom;
        gradientLayer3.startPoint = CGPointMake(0, 0);
        gradientLayer3.endPoint = CGPointMake(0, 1);
        
        [self.layer addSublayer:gradientLayer1];
        [gradientLayer1 addSublayer:gradientLayer2];
        [gradientLayer1 addSublayer:gradientLayer3];
        [gradientLayer1 setLocations:@[@0.35,@0.5,@0.75]];
        [gradientLayer3 setLocations:@[@0.2,@0.5,@0.75]];
        [gradientLayer2 setLocations:@[@0.2,@0.5,@0.75]];
    }
    return self;
}

- (NSMutableArray *)colorsTop {
    if (!_colorsTop) {
        _colorsTop = [NSMutableArray array];
        [_colorsTop addObject:(__bridge id)RGB(0xe2, 0xf2, 0x69).CGColor];
        [_colorsTop addObject:(__bridge id)RGB(0xff, 0xcf, 0x57).CGColor];
        [_colorsTop addObject:(__bridge id)RGB(0xff, 0xa8, 0x4c).CGColor];
    }
    return _colorsTop;
}

- (NSMutableArray *)colorsLeftBottom {
    if (!_colorsLeftBottom) {
        _colorsLeftBottom = [NSMutableArray array];
        [_colorsLeftBottom addObject:(__bridge id)RGB(0x73, 0xf2, 0x92).CGColor];
        [_colorsLeftBottom addObject:(__bridge id)RGB(0xab, 0xf2, 0x6e).CGColor];
        [_colorsLeftBottom addObject:(__bridge id)RGB(0xe2, 0xf2, 0x69).CGColor];
    }
    return _colorsLeftBottom;
}

- (NSMutableArray *)colorsRightBottom {
    if (!_colorsRightBottom) {
        _colorsRightBottom = [NSMutableArray array];
        [_colorsRightBottom addObject:(__bridge id)RGB(0xff, 0xa8, 0x4c).CGColor];
        [_colorsRightBottom addObject:(__bridge id)RGB(0xff, 0x80, 0x4c).CGColor];
        [_colorsRightBottom addObject:(__bridge id)RGB(0xe2, 0x56, 0x4c).CGColor];
    }
    return _colorsRightBottom;
}

- (void)setPercent:(CGFloat)percent {
//    _shapeLayer.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.frame.size.width * 0.5, self.frame.size.height * 0.5 + 110) radius:120 startAngle:degreesToRadians(150.f) endAngle:degreesToRadians(percent / 200.f * 240.f + 150.f) clockwise:1].CGPath;
    CGFloat value = percent / 200.f;   //計(jì)算進(jìn)度條的位置點(diǎn)
    _shapeLayer.strokeStart = MIN(0, value);
    _shapeLayer.strokeEnd = MAX(0, value);
}

關(guān)于CABasicAnimation,使用strokeStart和strokeEnd做動(dòng)畫(huà)時(shí),可以不添加這個(gè)animation,也是有動(dòng)畫(huà)效果的,在進(jìn)度條偶爾增大偶爾減少時(shí)我覺(jué)得用屬性設(shè)置的方式比較好。
關(guān)于設(shè)置漸變色的位置,在未添加gradientLayer的mask的效果如圖,這樣可以更清楚的看到,三種顏色過(guò)渡方式,上方為從左向右進(jìn)行過(guò)渡,左下方為從下到上進(jìn)行過(guò)渡,右下方為從上到下進(jìn)行過(guò)渡,看到整體效果后,再去添加mask,就可以實(shí)現(xiàn)一個(gè)平滑的弧形過(guò)渡啦。

IMG_0115.PNG
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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