iOS_動(dòng)畫_實(shí)例(2)_進(jìn)度條的實(shí)現(xiàn)+漸變進(jìn)度條的實(shí)現(xiàn)

一丶原理

先看下效果:

無漸變:
1.png

由2個(gè)圓環(huán),一個(gè)背景灰色圓環(huán)+一個(gè)進(jìn)度圓環(huán);

1.圓環(huán)

CAShapeLayer用來顯示樣式的圖層;

畫圓環(huán)的方式:

利用貝塞爾曲線繪制,添加到CAShapeLayer上:

//弧度=角度*3.14再除以180

- (void)addArcWithCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise NS_AVAILABLE_IOS(4_0);

注意

CAShapeLayer的lineCap屬性,設(shè)置線的頭部形狀;

有無形狀+圓形+方形;

/* The cap style used when stroking the path. Options are butt',round'

  • and square'. Defaults tobutt'. */
無形狀
 NSString *cons kCALineCapButt;
 圓形
 NSString *const kCALineCapRound;
 方形
 NSString *const kCALineCapSquare; 

2.畫漸變
漸變:

2.png

CAGradientLayer介紹:

漸變用到CAGradientLayer這個(gè)類;給用的api很少,也很簡潔;

/*

顏色數(shù)組锡溯,設(shè)置我們需要過的的顏色,必須是CGColor對象

*/

@property(nullable, copy) NSArray *colors;

/*

顏色開始進(jìn)行過渡的位置

這個(gè)數(shù)組中的元素是NSNumber類型,單調(diào)遞增的祭饭,并且在0——1之間

例如芜茵,如果我們設(shè)置兩個(gè)顏色進(jìn)行過渡,這個(gè)數(shù)組中寫入0.5倡蝙,則第一個(gè)顏色會(huì)在達(dá)到layer一半的時(shí)候開始向第二個(gè)顏色過渡

*/

@property(nullable, copy) NSArray<NSNumber *> *locations;

/*

下面兩個(gè)參數(shù)用于設(shè)置渲染顏色的起點(diǎn)和終點(diǎn) 取值范圍均為0——1

默認(rèn)起點(diǎn)為(0.5 九串,0) 終點(diǎn)為(0.5 ,1),顏色的過渡范圍就是沿y軸從上向下

*/

@property CGPoint startPoint;

@property CGPoint endPoint;

創(chuàng)建兩個(gè)CAGradientLayer;
右邊采用藍(lán)->黃色漸變;
左邊采用藍(lán)->黃色漸變;
用Layer把2個(gè)層拼接;
需要顯示的部分可以采用mask屬性進(jìn)行設(shè)置;
因?yàn)樾枰獔A環(huán),所以直接
_gradLayer.mask = self.frontShapeLayer;
就實(shí)現(xiàn)漸變圓環(huán);

要點(diǎn):
理論上一個(gè)CAGradientLayer就夠了;提供2個(gè)CAGradientLayer是運(yùn)輸可以設(shè)置3種顏色漸變;

二丶代碼

#import <UIKit/UIKit.h>

@interface ProgressView : UIView

@property (nonatomic, assign) CGFloat progress;
@property (nonatomic, assign,getter=isGradual) BOOL gradual;


/**
 @param gradual 開啟漸變,默認(rèn)關(guān)閉;
 */
- (void)setGradual:(BOOL)gradual;
/**
 @param progress 進(jìn)度 [0,1],默認(rèn)開啟
 */
- (void)setProgress:(CGFloat)progress;

@end
#import "ProgressView.h"

static const CGFloat kLineWidth = 5.0f;
static const CGFloat kFrontLineWidth = 5.0f;
#define kColor_Top [UIColor colorWithRed:34/255.0 green:44/255.0 blue:87/255.0 alpha:1]
#define kColor_Bottom [UIColor colorWithRed:223/255.0 green:157/255.0 blue:16/255.0 alpha:1]
#define kColor_Background [UIColor colorWithRed:225/255.0 green:224/255.0 blue:233/255.0 alpha:1]


@interface ProgressView ()



@property (strong, nonatomic) CAShapeLayer *frontShapeLayer;
@property (strong, nonatomic) CAShapeLayer *backShapeLayer;
@property (strong, nonatomic) UIBezierPath *circleBezierPath;
//漸變用
@property (nonatomic, strong) CAGradientLayer *rightGradLayer;
@property (nonatomic, strong) CAGradientLayer *leftGradLayer;
@property (nonatomic, strong) CALayer *gradLayer;

@end

@implementation ProgressView


-(void)drawRect:(CGRect)rect{
    
    CGFloat kWidth = rect.size.width;
    CGFloat kHeight = rect.size.height;
    
    if (!self.circleBezierPath){
        self.circleBezierPath = ({
            CGPoint pCenter = CGPointMake(kWidth * 0.5, kHeight * 0.5);
            CGFloat radius = MIN(kWidth, kHeight);
            radius = radius - kFrontLineWidth;
            UIBezierPath *circlePath = [UIBezierPath bezierPath];
            [circlePath addArcWithCenter:pCenter radius:radius * 0.5 startAngle:270 * M_PI / 180 endAngle:269 * M_PI / 180 clockwise:YES];
            [circlePath closePath];
            circlePath;
        });
    }
    if (!self.backShapeLayer) {
        self.backShapeLayer = ({
            CAShapeLayer *shapeLayer = [CAShapeLayer layer];
            shapeLayer.frame = rect;
            shapeLayer.path = self.circleBezierPath.CGPath;
            shapeLayer.fillColor = [UIColor clearColor].CGColor;
            shapeLayer.lineWidth = kLineWidth;
            shapeLayer.strokeColor = [UIColor colorWithWhite:0.886 alpha:1.000].CGColor;
            shapeLayer.lineCap = kCALineCapRound;
            [self.layer addSublayer:shapeLayer];
            shapeLayer;
        });
    }
    
    if (!self.frontShapeLayer){
        self.frontShapeLayer = ({
            CAShapeLayer  *shapeLayer = [CAShapeLayer layer];
            shapeLayer.frame = rect;
            shapeLayer.path = self.circleBezierPath.CGPath;
            shapeLayer.fillColor = [UIColor clearColor].CGColor;
            shapeLayer.lineWidth = kFrontLineWidth;
            shapeLayer.strokeColor = [UIColor colorWithRed:0.906 green:0.769 blue:0.125 alpha:1.000].CGColor;
            shapeLayer;
        });
        if (self.gradual) {
            [self addGradLayerWithRect:rect];
            self.frontShapeLayer.lineCap = kCALineCapRound;
            _gradLayer.mask = self.frontShapeLayer;
            [self.layer addSublayer:_gradLayer];
        }else{
            [self.layer addSublayer:self.frontShapeLayer];
        }
    }
    
     [self startAnimationValue:self.progress];
}
- (void)addGradLayerWithRect:(CGRect)rect{
    CGFloat kHeight = rect.size.height;
    CGRect viewRect = CGRectMake(0, 0, kHeight, kHeight);
    CGPoint centrePoint = CGPointMake(kHeight/2, kHeight/2);
    
    _leftGradLayer = ({
        CAGradientLayer *leftGradLayer = [CAGradientLayer layer];
        leftGradLayer.bounds = CGRectMake(0, 0, kHeight/2, kHeight);
        leftGradLayer.locations = @[@0.1];
        [leftGradLayer setColors:@[(id)kColor_Top.CGColor,(id)kColor_Bottom.CGColor]];
        leftGradLayer.position = CGPointMake(leftGradLayer.bounds.size.width/2, leftGradLayer.bounds.size.height/2);
        leftGradLayer;
    });
    _rightGradLayer = ({
        CAGradientLayer *rightGradLayer = [CAGradientLayer layer];
        rightGradLayer.locations = @[@0.1];
        rightGradLayer.bounds = CGRectMake(kHeight/2, 0, kHeight/2, kHeight);
        [rightGradLayer setColors:@[(id)kColor_Top.CGColor,(id)kColor_Bottom.CGColor]];
        rightGradLayer.position = CGPointMake(rightGradLayer.bounds.size.width/2+kHeight/2, rightGradLayer.bounds.size.height/2);
        rightGradLayer;
    });
    _gradLayer = ({
        CALayer *gradLayer = [CALayer layer];
        gradLayer.bounds = viewRect;
        gradLayer.position = centrePoint;
        gradLayer.backgroundColor = [UIColor clearColor].CGColor;
        gradLayer;
    });
    [_gradLayer addSublayer:_leftGradLayer];
    [_gradLayer addSublayer:_rightGradLayer];
}
- (void)startAnimationValue:(CGFloat)value{
    CABasicAnimation *pathAnima = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    pathAnima.duration = 1.0f;
    pathAnima.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    pathAnima.fromValue = [NSNumber numberWithFloat:0.0f];
    pathAnima.toValue = [NSNumber numberWithFloat:value];
    pathAnima.fillMode = kCAFillModeForwards;
    pathAnima.removedOnCompletion = NO;
    [self.frontShapeLayer addAnimation:pathAnima forKey:@"strokeEndAnimation"];
}

- (void)setGradual:(BOOL)gradual{
    _gradual = gradual;
    if (gradual) {
        [self.frontShapeLayer removeFromSuperlayer];
        self.frontShapeLayer = nil;
    }else{
        [_gradLayer removeFromSuperlayer];
        _gradLayer = nil;
        [self.frontShapeLayer removeFromSuperlayer];
        self.frontShapeLayer = nil;
    }
}
- (void)setProgress:(CGFloat)progress{
    NSAssert(progress >= 0 && progress <=1, @"超出范圍");
    _progress = progress;
    [self setNeedsDisplay];
}

@end

三丶代碼地址

https://github.com/k373379320/ZBProgressView

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末寺鸥,一起剝皮案震驚了整個(gè)濱河市猪钮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌胆建,老刑警劉巖烤低,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異眼坏,居然都是意外死亡拂玻,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門宰译,熙熙樓的掌柜王于貴愁眉苦臉地迎上來檐蚜,“玉大人,你說我怎么就攤上這事沿侈〈车冢” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵缀拭,是天一觀的道長咳短。 經(jīng)常有香客問我,道長蛛淋,這世上最難降的妖魔是什么咙好? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮褐荷,結(jié)果婚禮上勾效,老公的妹妹穿的比我還像新娘企软。我一直安慰自己驼壶,他們只是感情好避咆,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布稽犁。 她就那樣靜靜地躺著富纸,像睡著了一般丘薛。 火紅的嫁衣襯著肌膚如雪腻暮。 梳的紋絲不亂的頭發(fā)上讥珍,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天抖苦,我揣著相機(jī)與錄音毁菱,去河邊找鬼米死。 笑死,一個(gè)胖子當(dāng)著我的面吹牛鼎俘,可吹牛的內(nèi)容都是我干的哲身。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼贸伐,長吁一口氣:“原來是場噩夢啊……” “哼勘天!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起捉邢,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤脯丝,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后伏伐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宠进,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年藐翎,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了材蹬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡吝镣,死狀恐怖堤器,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情末贾,我是刑警寧澤闸溃,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站拱撵,受9級(jí)特大地震影響辉川,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拴测,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一乓旗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧集索,春花似錦屿愚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽扰法。三九已至蛹含,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間塞颁,已是汗流浹背浦箱。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來泰國打工吸耿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人酷窥。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓咽安,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蓬推。 傳聞我的和親對象是個(gè)殘疾皇子妆棒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容