

實現(xiàn)思路
- 定義一個View
- 運用CGMutablePathRef 和CAShapeLayer畫出靜態(tài)正弦函數(shù)
- 運用幀顯示類CADisplayLink,不斷的改變路徑上的各個點,讓波浪動起來
- 回調(diào)每一幀的中點值,可以增加動態(tài)的圓形等自定義視圖
三角函數(shù)
假設 y = Asin(ωx+φ)+ C
A 表示振幅,也就是使用這個變量來調(diào)整波浪的最大的高度
ω 與周期相關,周期 T = 2 x pi / ω ,這個變量用來調(diào)整同寬度內(nèi)顯示的波浪的數(shù)量
φ 表示波浪橫向的偏移,也就是使用這個變量來調(diào)整波浪的流動
C 表示波浪縱向偏移的位置。
正弦函數(shù)伸縮變換
三角函數(shù)平移變換和周期變換
CADisplayLink
一種精確到幀的定時器,其根本是利用刷幀和屏幕頻率一樣來重繪渲染頁面。
注意1:初始CADisplayLink對象,指定target的時候,其屬于單例,會保留其目標對象,而CADisplayLink的目標對象如果恰好保留了計時器本身,就會導致循環(huán)引用。
注意2:frameInterval的值默認為1,真機刷新頻率是每秒60次,所以每一次調(diào)用的“target”函數(shù)的運行的時間大于1/60秒,就會出現(xiàn)嚴重的丟幀現(xiàn)象。frameInterval的值默認為2時,刷新頻率就變?yōu)榱嗣棵?0次。
其創(chuàng)建方式:
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(wave)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
NSRunLoop
什么是run loop ,簡單說下:讓線程在有任務的時候忙于工作,而沒任務的時候處于休眠狀態(tài)。
run loop線程開啟的時候便被創(chuàng)建,所以只需要在當前線程獲取即可。
- NSDefaultRunLoopMode
App的默認 Mode,通常主線程是在這個 Mode 下運行的。 - UITrackingRunLoopMode
界面跟蹤 Mode,用于 ScrollView 追蹤觸摸滑動,保證界面滑動時不受其他 Mode 影響。 - NSRunLoopCommonModes
公共的mode,即是這個Mode下的事件,可以在其他的Mode下被運行。
CADisplayLink、NSTimer執(zhí)行的小動畫,在拖動scrollView的時候動畫會被暫停,此時就需要設置所加在的run loop 的mode了。
主要代碼:
//創(chuàng)建浪的路徑
CGMutablePathRef wavePath = CGPathCreateMutable();
//創(chuàng)建一個起點
CGPathMoveToPoint(wavePath, NULL, 0, height);
//創(chuàng)建中間點
for (int x = 0; x < width; x++) {
//主要的實現(xiàn)算法就是y = Asin(ωx+φ)
CGFloat y = height * sinf(self.waveCurve * x * M_PI / 180 + offset * M_PI / 180);
CGPathAddLineToPoint(wavePath, NULL, x, y);
}
//調(diào)整填充路徑
CGPathAddLineToPoint(wavePath, NULL, width, height);
CGPathAddLineToPoint(wavePath, NULL, 0, height);
//結(jié)束路徑
CGPathCloseSubpath(wavePath);
//用路徑創(chuàng)建浪
waveShapeLayer.path = wavePath;
waveShapeLayer.fillColor = waveWolor.CGColor;
//釋放浪路徑
CGPathRelease(wavePath);
當開始動畫的時候?qū)ADisplayLink對象加到runLoop中
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
結(jié)束動畫時注銷掉CADisplayLink對象
[self.displayLink invalidate];
self.displayLink = nil;
更多內(nèi)容,請在Demo中查看,F(xiàn)YJWave可導入直接使用~
Demo下載地址