小弟才疏學(xué)淺腋颠,第一次寫簡書文章繁成,內(nèi)容難免有錯誤或者不妥吓笙,歡迎大家來指點江山淑玫。。面睛。
先來看一下最終的效果:
特點:圓環(huán)是順時針旋轉(zhuǎn)絮蒿,旋轉(zhuǎn)的過程中,始終保持圓環(huán)的開始端顏色最淺(白色)叁鉴,圓環(huán)的結(jié)尾是最深(0xEC1161).
在剛開始要做這個東西的時候土涝,是因為想做一個下拉刷新的動畫,這個動畫要做到在下拉的過程中幌墓,有一個顏色漸變的圓環(huán)在變大但壮,而且是要始終保濕圓環(huán)的開頭是白色,圓環(huán)的結(jié)尾是0xEC1161最深色常侣。
想了幾個方法蜡饵,都不太理想,其中包括在圓環(huán)的底部放置一個圓環(huán)圖片胳施,下拉過程中溯祸,拖過CALayer的mask功能來把需要顯示的圓環(huán)給扣出來顯示,最終我采用了最簡單的方式,就是直接無限旋轉(zhuǎn)一個圓環(huán)圖片焦辅,醉了博杖。。
這事完了之后筷登,我不甘心剃根,決定好好來實現(xiàn)以下這個動畫效果,就來了這個前方;下面簡要分析寫這個動畫的實現(xiàn)邏輯(可能對后續(xù)要實現(xiàn)一個進(jìn)度條或者類似于360安全衛(wèi)士清理時的進(jìn)度條有一定的幫助)跟继。
1. 這個圓環(huán)底部是一個UIView,在UIView上添加N(N>=2)個扇形的漸變CAGradientLayer镣丑,并讓這幾個扇形漸變的層正好布滿這個圓舔糖;
2. 這一系列扇形的CAGradientLayer的制作方法是:
a) 先畫一個UIView上半部分大小的CAGradientLayer;
b) 計算CAGradientLayer的startPoint和endPoint莺匠,這倆值的大小是根據(jù)1中的N決定的金吗,N越大,endPoint.x-startPoint.x越小趣竣,而且endPoint.x和startPoint.x是以0.5為中心向兩邊偏移相等的距離摇庙,startPoint.x=0.5-sin(1.f/N*M_PI)/2.f,endPoint.x=0.5+sin(1.f/N*M_PI)/2.f遥缕,這里用到了簡單的直角三角形的sin函數(shù)計算卫袒;
c) 制作一個扇形的Layer,并把這個扇形Layer作為CAGradientLayer的mask单匣,扇形Layer的UIBezierPath的繪制也是以中間為軸夕凝,向兩邊偏移,偏移的大小b中的計算是一樣的户秤,startAngle=(-90.f/180.f*M_PI - 1.f/N*M_PI)码秉, endAngle=(-90.f/180.f*M_PI + 1.f/N*M_PI)
d) 最后,按照添加的次序鸡号,依次旋轉(zhuǎn)CAGradientLayer转砖,使得N個Layer正好鋪成一個圓;
3. 然后在最上層添加一個CAShapeLayer鲸伴,并且讓這個layer的frame的大小比最底層的UIView的frame稍微小一點(這個差值就是圓環(huán)的粗細(xì))府蔗,同時讓這個Layer的position等于UIView的center;
4. 稍微旋轉(zhuǎn)下最上層的CAShapeLayer汞窗,以做到等下針對該Layer的strokeStart做動畫時姓赤,能夠從中標(biāo)的0點鐘位置開始,順時針方向做動畫;
5. 下面是動畫的部分杉辙,動畫分為兩個步驟模捂,一個是針對oval.strokeStart的動畫捶朵,一個是針對N各扇形layer的locations的動畫
a) 針對oval.strokeStart的動畫簡單,執(zhí)行N個單位時間狂男,直接添加該動畫即可综看;
b) 針對N各扇形的動畫,是依次延遲 i (i從0開始)執(zhí)行的岖食,執(zhí)行N-i個單位時間红碑,并且每一個扇形的locations的開始值得第一個值是-i,第二個值是0泡垃,而且結(jié)束值得第一個值不變析珊,第二個值是N-1,這是為什么呢?是因為要做到N個扇形的顏色能夠無縫銜接蔑穴,具體原因上代碼(Talk is cheap, show me the code.)忠寻,大家一看便明了(注:在初始化扇形Layer的時候,已經(jīng)指定過了layer.locations=@[@(-i),@0.f]);
至此存和,大功告成奕剃,GradientLayerCount的值就是N,可以隨意修改配置捐腿,但是要保證大于等于2.
最后附上項目完整代碼鏈接(https://github.com/ShakeShakeMe/CircleProcessBar)纵朋。
修改:修改為可以手動執(zhí)行動畫(也就是通過滑塊來執(zhí)行動畫)。
(歡迎大家來踩)