個人中心波浪特效

相信很多人見過app個人中心的波浪動畫效果吧,是不是覺得很酷?
接下來家夺,我會給大家分享一個實現(xiàn)的思路。
先上圖佣蓉,看看效果披摄。


jswave.gif

忽略掉這個晃眼的紅色(畢竟只是用來做示例),這個波浪效果很帶感吧勇凭。

簡單原理疚膊,CAShapeLayer 結(jié)合CGPath繪制圖形。
動畫操作的是CAShapeLayer(CALayer的子類)層虾标,而非直接操作UIView寓盗。
CAShapeLayer在渲染速度,顯示效果璧函,內(nèi)存占用傀蚌,資源消耗上均有不小優(yōu)勢。對于CALayer和UIView的區(qū)別以及CAShapeLayer不是很了解的讀者蘸吓,可以閱讀我在文章結(jié)尾附上的相關(guān)知識鏈接善炫。

看代碼實現(xiàn)部分
<pre><code>
@interface ZSWave : UIView

@property (nonatomic, assign) CGFloat waveSpeed;//浪彎曲度

@property (nonatomic, assign) CGFloat speed;//浪速

@property (nonatomic, assign) CGFloat waveHeight;//浪高

@property (nonatomic, strong) UIColor *realWaveColor;//實浪顏色

@property (nonatomic, strong) UIColor *maskWaveColor;//遮罩浪顏色

@property (nonatomic, strong) UIView *headerImageWallView;//頭像父視圖

- (void)stopWaveAnimation;

- (void)startWaveAnimation;

@end
</pre></code>
<pre><code>
@interface ZSWave ()

@property (nonatomic, strong) CADisplayLink *timer;//刷屏器

@property (nonatomic, strong) CAShapeLayer *realWaveLayer;//真實浪

@property (nonatomic, strong) CAShapeLayer *maskWaveLayer;//遮罩浪

@property (nonatomic, assign) CGFloat offset;

@end

</pre></code>
<pre><code>
- (instancetype)initWithFrame:(CGRect)frame
{
if ([super initWithFrame:frame]) {
[self initData];
}
return self;
}

- (void)initData{

[self.layer addSublayer:self.realWaveLayer];
[self.layer addSublayer:self.maskWaveLayer];
[self addSubview:self.headerImageWallView];

[self startWaveAnimation];

}

- (void)startWaveAnimation{

self.timer = [CADisplayLink displayLinkWithTarget:self selector:@selector(wave)];
[self.timer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];

}

- (void)stopWaveAnimation{

[self.timer invalidate];
self.timer = nil;

}

</pre></code>

核心代碼

<pre><code>
- (void)wave{

[self layoutIfNeeded];

self.offset += self.speed;

CGFloat width = CGRectGetWidth(self.frame);
CGFloat height = CGRectGetHeight(self.frame);

//真實浪
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 0, height );
CGFloat y = 0.f;
for (CGFloat x = 0.f; x <= width ; x++) {
    y = height * sinf(0.01 * self.waveSpeed * x + self.offset * 0.045);
    CGPathAddLineToPoint(path, NULL, x, y);
}

CGFloat centX = self.center.x;
CGFloat CentY = height * sinf(0.01 * self.waveSpeed *centX  + self.offset * 0.045);
CGRect iconFrame = [self.headerImageWallView frame];
iconFrame.origin.y = CentY - iconFrame.size.height;
self.headerImageWallView.frame  =iconFrame; //調(diào)整頭像位置,隨波浪運動
CGPathAddLineToPoint(path, NULL, width, height);
CGPathAddLineToPoint(path, NULL, 0, height);
CGPathCloseSubpath(path);
self.realWaveLayer.path = path;
self.realWaveLayer.fillColor = self.realWaveColor.CGColor;
CGPathRelease(path);
//遮罩浪
CGMutablePathRef maskpath = CGPathCreateMutable();
CGPathMoveToPoint(maskpath, NULL, 0, height);
CGFloat maskY = 0.f;
for (CGFloat x = 0.f; x <= width ; x++) {
    maskY = height * cosf(0.01 * self.waveSpeed * x + self.offset * 0.045);
    CGPathAddLineToPoint(maskpath, NULL, x, maskY);
}
CGPathAddLineToPoint(maskpath, NULL, width, height);
CGPathAddLineToPoint(maskpath, NULL, 0, height);
CGPathCloseSubpath(maskpath);
self.maskWaveLayer.path = maskpath;
self.maskWaveLayer.fillColor = self.maskWaveColor.CGColor;
CGPathRelease(maskpath);

}

</pre></code>
默認屬性設(shè)置及初始化
<pre><code>
#pragma mark - Initialize parameter

- (CGFloat)waveSpeed {

if (!_waveSpeed) {
    _waveSpeed = 1.5;
}
return _waveSpeed;

}

- (CGFloat)speed {

if (!_speed) {
    _speed = 0.7;
}
return _speed;

}

- (CGFloat)waveHeight {

if (!_waveHeight) {
    _waveHeight = 5;
}
return _waveHeight;

}

- (UIColor *)realWaveColor {

if (!_realWaveColor) {
    _realWaveColor = [UIColor whiteColor];
}
return _realWaveColor;

}

- (UIColor *)maskWaveColor {

if (!_maskWaveColor) {
    _maskWaveColor = [[UIColor whiteColor]colorWithAlphaComponent:0.3];
}
return _maskWaveColor;

}

#pragma mark - lazy loading

- (CAShapeLayer *)realWaveLayer{

if (!_realWaveLayer) {
    _realWaveLayer = [CAShapeLayer layer];
    _realWaveLayer.frame =  self.bounds;
    _realWaveLayer.fillColor = self.realWaveColor.CGColor;
    
}
return _realWaveLayer;

}

- (CAShapeLayer *)maskWaveLayer{

if (!_maskWaveLayer) {
    _maskWaveLayer = [CAShapeLayer layer];
    _maskWaveLayer.frame =  self.bounds;
    _maskWaveLayer.fillColor = self.maskWaveColor.CGColor;
}
return _maskWaveLayer;

}

- (UIView *)headerImageWallView {

if (!_headerImageWallView) {
    _headerImageWallView = [[UIView alloc]initWithFrame:CGRectMake(self.center.x - 30, -60, 60, 60)];
    _headerImageWallView.layer.borderColor = [UIColor whiteColor].CGColor;
    _headerImageWallView.layer.borderWidth = 2;
    _headerImageWallView.layer.cornerRadius = 20;
}
return _headerImageWallView;

}

</pre></code>
最后一定記得重寫dealloc库继,把定時器注銷箩艺。
<pre><code>
- (void)dealloc{

[self stopWaveAnimation];

}
</pre></code>
參考資料CADisplayLinkCALayer和UIView的區(qū)別

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末宪萄,一起剝皮案震驚了整個濱河市艺谆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拜英,老刑警劉巖静汤,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異居凶,居然都是意外死亡虫给,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進店門排监,熙熙樓的掌柜王于貴愁眉苦臉地迎上來狰右,“玉大人杰捂,你說我怎么就攤上這事舆床。” “怎么了嫁佳?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵挨队,是天一觀的道長。 經(jīng)常有香客問我蒿往,道長盛垦,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任瓤漏,我火速辦了婚禮腾夯,結(jié)果婚禮上颊埃,老公的妹妹穿的比我還像新娘。我一直安慰自己蝶俱,他們只是感情好班利,可當(dāng)我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著榨呆,像睡著了一般罗标。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上积蜻,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天闯割,我揣著相機與錄音,去河邊找鬼竿拆。 笑死宙拉,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的丙笋。 我是一名探鬼主播鼓黔,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼不见!你這毒婦竟也來了澳化?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤稳吮,失蹤者是張志新(化名)和其女友劉穎缎谷,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體灶似,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡列林,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了酪惭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片希痴。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖春感,靈堂內(nèi)的尸體忽然破棺而出砌创,到底是詐尸還是另有隱情,我是刑警寧澤鲫懒,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布嫩实,位于F島的核電站,受9級特大地震影響窥岩,放射性物質(zhì)發(fā)生泄漏甲献。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一颂翼、第九天 我趴在偏房一處隱蔽的房頂上張望晃洒。 院中可真熱鬧慨灭,春花似錦、人聲如沸球及。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽桶略。三九已至语淘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間际歼,已是汗流浹背惶翻。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留鹅心,地道東北人吕粗。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像旭愧,于是被迫代替她去往敵國和親颅筋。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,876評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫输枯、插件议泵、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,124評論 4 61
  • 會議開始之前我們先來回顧一下學(xué)習(xí)千里馬的點點滴滴 千里馬河南戰(zhàn)區(qū)陳國鵬大將軍為偉仕商貿(mào)主持60天啟動大會!從9月份...
    河南千里馬閱讀 657評論 0 1
  • 原計劃第二天下午桃熄,就入村給當(dāng)?shù)氐睦相l(xiāng)剝蓮子先口。大中午出去轉(zhuǎn)了一圈,卻沒有找到需要幫忙的人家瞳收。老鄉(xiāng)說早上才有蓮子...
    伏羲師范熊芳閱讀 936評論 0 1
  • 前不久到一處學(xué)械锞看管理情況,發(fā)現(xiàn)學(xué)校還存在一些臟亂的地方螟深,校長對我說谐宙,等搬到新樓上以后我好好抓一抓。我說你這...
    松峰說教劉樹森閱讀 271評論 0 1
  • 我永遠都知道這樣抱怨沒有任何效果 可我就是忍不了 好像這世界上的每個人 ?不抱怨就活不了
    111林晝歌閱讀 99評論 0 0