IOS動畫系列之炫酷的進(jìn)度條

老規(guī)矩,先上這個動畫的效果圖。


los_ani.gif

先來說說這個動畫用到了哪些知識吧!

  1. UIGraphicsGetCurrentContext,它是什么呢?它就是我們繪圖會用到的圖形當(dāng)前的上下文。
    1.1 獲取當(dāng)前的上下文(這里只能獲取一次,并且只能在drawRect方法中獲?。?。
    1.2 描述路徑、形狀(就是處理想要顯示的樣子)。
    1.3 把描述好的路徑、形狀添加早上下文中。
    1.4 顯示上下文內(nèi)容。
void drawHu1()
{
    //1.獲取上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    
    //1.1 設(shè)置線條的寬度
    CGContextSetLineWidth(ctx, 10);
    //1.2 設(shè)置線條的起始點(diǎn)樣式
    CGContextSetLineCap(ctx,kCGLineCapButt);
    //1.3  虛實(shí)切換 ,實(shí)線2虛線8
    CGFloat length[] = {2,8};
    CGContextSetLineDash(ctx, 0, length, 2);
    //1.4 設(shè)置顏色
    [[UIColor lightGrayColor] set];
    //2.設(shè)置路徑
    CGContextAddArc(ctx, kScreenW/2 , kScreenW/2, 95, -5*M_PI_4, M_PI_4, 0);
    //3.繪制
    CGContextStrokePath(ctx);
}

例如上面這段代碼,這段代碼的功能是繪制灰色條形的進(jìn)度條,里面的相關(guān)屬性我已經(jīng)說明了。

  1. NSTimer:當(dāng)使用NSTimer的scheduledTimerWithTimeInterval方法時。事實(shí)上此時Timer會被加入到當(dāng)前線程的Run Loop中,且模式是默認(rèn)的NSDefaultRunLoopMode。而如果當(dāng)前線程就是主線程,也就是UI線程時,某些UI事件,比如UIScrollView的拖動操作,會將Run Loop切換成NSEventTrackingRunLoopMode模式,在這個過程中,默認(rèn)的NSDefaultRunLoopMode模式中注冊的事件是不會被執(zhí)行的。也就是說,此時使用scheduledTimerWithTimeInterval添加到Run Loop中的Timer就不會執(zhí)行。
[NSTimer scheduledTimerWithTimeInterval:.02 target:self selector:@selector(change) userInfo:nil repeats:YES]

這兒在主線程中會每隔0.02s就會調(diào)用change方法,這兒的作用是改變label中的文字。

  1. CAShapeLayer和CAGradientLayer的用法:

3.1 CAShapeLayer是一個通過矢量圖形而不是bitmap來繪制的圖層子類。你指定諸如顏色和線寬等屬性,用CGPath來定義想要繪制的圖形,最后CAShapeLayer就自動渲染出來了。當(dāng)然,你也可以用Core Graphics直接向原始的CALyer的內(nèi)容中繪制一個路徑,相比直下,使用CAShapeLayer有以下一些優(yōu)點(diǎn):

a.渲染快速,CAShapeLayer使用了硬件加速,繪制同一圖形會比用Core Graphics快很多。
b.高效使用內(nèi)存,一個CAShapeLayer不需要像普通CALayer一樣創(chuàng)建一個寄宿圖形,所以無論有多大,都不會占用太多的內(nèi)存。
c.不會被圖層邊界剪裁掉,一個CAShapeLayer可以在邊界之外繪制。你的圖層路徑不會像在使用Core Graphics的普通CALayer一樣被剪裁掉。
d.不會出現(xiàn)像素化,當(dāng)你給CAShapeLayer做3D變換時,它不像一個有寄宿圖的普通圖層一樣變得像素化。 
  1. CGPath
CAShapeLayer可以用來繪制所有能夠通過CGPath來表示的形狀。
這個形狀不一定要閉合,圖層路徑也不一定要不可破,事實(shí)上你可以在一個圖層上繪制好幾個不同的形狀。
你可以控制一些屬性比如lineWith(線寬,用點(diǎn)表示單位),lineCap(線條結(jié)尾的樣子),和lineJoin(線條之間的結(jié)合點(diǎn)的樣子);
但是在圖層層面你只有一次機(jī)會設(shè)置這些屬性。
如果你想用不同顏色或風(fēng)格來繪制多個形狀,就不得不為每個形狀準(zhǔn)備一個圖層了。
  1. CAGradientLayer
屬性:
colors:顏色數(shù)組
locations:設(shè)置每個顏色對應(yīng)的起始點(diǎn)
startPoint:漸變開始的位置
endPoint:漸變結(jié)束的位置
type:只有默認(rèn)值,可不設(shè)置
  1. CAKeyframeAnimation和CGMutablePathRef。
// 設(shè)置動畫屬性
    CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    pathAnimation.calculationMode = kCAAnimationPaced;
    pathAnimation.fillMode = kCAFillModeForwards;
    pathAnimation.removedOnCompletion = NO;
    pathAnimation.duration = kAnimationTime;
    pathAnimation.repeatCount = 1;
    
    // 設(shè)置動畫路徑
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddArc(path, NULL, self.width / 2, self.width / 2, (self.circelRadius + 1 - kMarkerRadius / 2) / 2, startAngle, endAngle, 0);
    pathAnimation.path = path;
    CGPathRelease(path);
    
    self.markerImageView.frame = CGRectMake(-100, self.height, kMarkerRadius, kMarkerRadius);
    self.markerImageView.layer.cornerRadius = self.markerImageView.frame.size.height / 2;
    [self addSubview:self.markerImageView];
    
    [self.markerImageView.layer addAnimation:pathAnimation forKey:@"moveMarker"];

這段代碼中主要設(shè)置一個自定義路徑和一個幀動畫,這樣去設(shè)置光標(biāo)的路徑動畫。

尾言:
本來我想做成這樣的動畫,但發(fā)現(xiàn)進(jìn)度條的顏色并不能進(jìn)行顏色的漸變。
原因:我用的是圖形上下文去繪制條形進(jìn)度,每次繪制會覆蓋之前的顏色,所以如果是漸變的,目前沒有想到好的方法,如果你看到這兒了,并且有好的方法,可以留言,之后在一起交流。


ios_ani.png

[地址]:https://github.com/CoDancer/DynamicCircleProgress

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

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

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