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

los_ani.gif
先來說說這個動畫用到了哪些知識吧!
- 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)說明了。
- 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中的文字。
- 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變換時,它不像一個有寄宿圖的普通圖層一樣變得像素化。
- CGPath
CAShapeLayer可以用來繪制所有能夠通過CGPath來表示的形狀。
這個形狀不一定要閉合,圖層路徑也不一定要不可破,事實(shí)上你可以在一個圖層上繪制好幾個不同的形狀。
你可以控制一些屬性比如lineWith(線寬,用點(diǎn)表示單位),lineCap(線條結(jié)尾的樣子),和lineJoin(線條之間的結(jié)合點(diǎn)的樣子);
但是在圖層層面你只有一次機(jī)會設(shè)置這些屬性。
如果你想用不同顏色或風(fēng)格來繪制多個形狀,就不得不為每個形狀準(zhǔn)備一個圖層了。
- CAGradientLayer
屬性:
colors:顏色數(shù)組
locations:設(shè)置每個顏色對應(yīng)的起始點(diǎn)
startPoint:漸變開始的位置
endPoint:漸變結(jié)束的位置
type:只有默認(rèn)值,可不設(shè)置
- 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