滴滴里面有一個下單完成之后等待界面的倒計時轉(zhuǎn)圈的視圖...

91CEFCE7-330C-4107-A69A-11F7DFE8021C.png
原理:
通過CAShapeLayer層添加到自己自定義的視圖layer上...
設(shè)置ShapeLayer的path...
他的路勁繪制一般通過UIBezierPath配合設(shè)置...
通過layer的StrokeEnd,StrokeStart設(shè)置path路徑上的起點和終點...
可以直接通過設(shè)置這兩個點就有平滑的東西效果...
先看效果...

D71FD6E7-BFCF-481E-B9FF-A8DD0B44246B.png
看左邊視圖...
分成三部分...
紅色進度變化的一個ShapeLayer...
底部灰色背景的一個ShapeLayer...
頭部綠色方向的一個ShapeLayer...
主要是綠色的那部分是通過實時計算它的strokestart和strokeend來控制他始終就是那么一個長度...
計算過程...

D4B300BC-E766-4F1A-BC6C-9A92D06557BF.png
圖中黃色為頭部那個點(s1)...
灰色為底部大圓的四分之一(s2)...
要計算出這個s1的strokeStart,strokeEnd之間的差值就是需要計算出s2所在s1中周長所占的比例...
這個比例如果轉(zhuǎn)化成弧度或者角度比的話就可以通過a角度來計算...
根據(jù)余弦定理:
cosa = (b*b+c*c-a*a)/(2*b*c)
就可得出a的弧度值...
換算比例就是stroke的start和end的差值...
主要代碼:
//計算這個point的start和end所占用這個角弧度值
//余弦定理 cosc = (a*a + b*b - c*c)/(2*a*b);
float radian = cosf((self.radius*self.radius+self.radius*self.radius - (self.pointRadius*2)*(self.pointRadius*2)))/(2*self.radius*self.radius);
//頭部點所占路勁的周長
float offsetProgress = radian/(M_PI*2);
_pointAnimatedLayer.strokeStart = _strokeEnd-offsetProgress;
_pointAnimatedLayer.strokeEnd = MIN(_strokeEnd, 1);

93C03F05-24B2-4413-A46F-069400038EA2.png
項目地址在這里....
其中的CAShapeLayer-Progress....
如果需要的話 可以自己去改改...