iOS 基于CAShapeLayer以及UIBezierPath的語音輸入效果動(dòng)畫封裝

先看效果圖

voiceinput.gif

要想完成上面顯示的效果要用到CAShapeLayer以及UIBezierPath一起完成。

那就先來了解一下什么是CAShapeLayer和UIBeizerPath:

  • CAShapeLayer:CAShapeLayer顧名思義,繼承于CALayer湿弦。 每個(gè)CAShapeLayer對(duì)象都代表著將要被渲染到屏幕上的一個(gè)任意的形狀(shape)。具體的形狀由其path(類型為CGPathRef)屬性指定。 普通的CALayer是矩形勿璃,所以需要frame屬性。CAShapeLayer初始化時(shí)也需要指定frame值推汽,但它本身沒有形狀补疑,它的形狀來源于其屬性path 。CAShapeLayer有不同于CALayer的屬性歹撒,它從CALayer繼承而來的屬性在繪制時(shí)是不起作用的莲组。

  • UIBeizerPath:UIBezierPath是在 UIKit 中的一個(gè)類,繼承于NSObject,可以創(chuàng)建基于矢量的路徑.此類是Core Graphics框架關(guān)于path的一個(gè)OC封裝暖夭。使用此類可以定義常見的圓形锹杈、多邊形等形狀 。我們使用直線迈着、唤咄(arc)來創(chuàng)建復(fù)雜的曲線形狀。每一個(gè)直線段或者曲線段的結(jié)束的地方是下一個(gè)的開始的地方寥假。每一個(gè)連接的直線或者曲線段的集合成為subpath市框。一個(gè)UIBezierPath對(duì)象定義一個(gè)完整的路徑包括一個(gè)或者多個(gè)subpaths。

關(guān)于CAShapeLayer的一些基本屬性可以參考:http://blog.csdn.net/yongyinmg/article/details/38755955

關(guān)于UIBezierPath的一些基本方法:

  • + (instancetype)bezierPathWithRect:(CGRect)rect;

矩形

  • +(instancetype)bezierPathWithOvalInRect:(CGRect)rect;

創(chuàng)建圓形或者橢圓形

  • +(instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius;

圓角矩形

  • +(instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;

圓弧

更多的方法和介紹可以參考 http://justsee.iteye.com/blog/1972853

接下來開始分析動(dòng)畫:

  1. 都包含一個(gè)小話筒
  2. 小話筒可以是實(shí)心的或者飛實(shí)心
  3. 包含標(biāo)題
  4. 都有一個(gè)半透明的灰色背景

小話筒 作者這里把話筒看成了4糕韧、5個(gè)部分枫振。

  1. 一個(gè)圓角長方形的邊框 (通過設(shè)置 fillColor 和 strokeColor)
  2. 一個(gè)圓角長方形的矩形 (通過設(shè)置 fillColor 和 strokeColor,這里只有在是第一種動(dòng)畫效果的時(shí)候才需要設(shè)置)
  3. 一個(gè)圓弧
  4. 一個(gè)連接圓弧的小圓角矩形 (垂直方向)
  5. 一個(gè)小圓角矩形(水平方向)
    通過以上的設(shè)置萤彩,我們的小話筒就創(chuàng)建出來了粪滤。
部分代碼:
- (CAShapeLayer*)drawOutSideLine:(CGRect)frame color:(UIColor*)color isFill:(BOOL)fill {
    CAShapeLayer * Layer = [CAShapeLayer new];
    if (fill) {
        Layer.fillColor = color.CGColor;
        Layer.strokeColor = nil;
    }
    else{
        Layer.fillColor = nil; //這個(gè)是填充顏色
        Layer.strokeColor = color.CGColor; //這個(gè)邊框顏色
    }
    
    Layer.frame = frame; //這個(gè)是大小
    Layer.lineWidth = self.lineWidth; //這個(gè)是線寬
    Layer.lineCap = kCALineCapRound; //線條拐角
    //這個(gè)就是畫圖
    Layer.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, frame.size.width, frame.size.height)  cornerRadius:frame.size.width*0.4].CGPath;
    return Layer;
}
參數(shù)1:大小
參數(shù)2:顏色
參數(shù)3:是不是填充色 
通過上述方法就可以完成對(duì)話筒最上面的部分進(jìn)行繪制


對(duì)于第一種動(dòng)畫效果,如何進(jìn)行更新:作者是這樣子處理的雀扶,如果有更好的方法杖小,歡迎提建議。
- (void)updateVoiceViewWithVolume:(float)volume{
    CGFloat height = self.colidView.height;
    CGFloat newHeight = height*volume;
    CGFloat width = self.colidView.width;
    
    self.colidLayer.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, height - newHeight , width , newHeight) cornerRadius:0].CGPath;
}
通過得到現(xiàn)在的高度愚墓,在把要顯示的高度計(jì)算出來
在通過修改y的坐標(biāo)以及修改現(xiàn)在要顯示的高度予权。
這樣子雖然可以完成效果,但是每次都需要重新繪制浪册。

- (void)setUp{
    self.circleLayer = [CAShapeLayer new];
    self.circleLayer.lineWidth = self.lineWidth*0.5;
    self.circleLayer.fillColor = nil;
    self.circleLayer.strokeColor = self.lineColor.CGColor;
    self.circleLayer.frame = self.bounds;
    self.circleLayer.lineCap = kCALineCapRound;
    self.circleLayer.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.width/2, self.height/2) radius:self.width*self.size startAngle:PQ_RADIANS(0) endAngle:PQ_RADIANS(360) clockwise:YES].CGPath;
    [self.layer addSublayer:self.circleLayer];
    
}
因?yàn)槎嗵幨褂玫絪hapeLayer繪制圓扫腺,所以作者就封裝了一個(gè)只用于畫圓的類,
通過上述方法可以創(chuàng)建一個(gè)圓形邊框村象,當(dāng)然也只需要修改一下 fillColor笆环,馬上就可以變成一個(gè)實(shí)心圓攒至。


- (void)createLayerWayTwo:(float)duration{
    
    __block PQVoiceCircleView *circleView = [[PQVoiceCircleView alloc]initWithFrame:self.bounds lineWidth:self.lineWidth lindeColor:self.lineColor size:0.5];
    [self addSubview:circleView];
    
    [UIView animateWithDuration:duration delay:0 options:(UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction) animations:^{
        circleView.layer.transform = CATransform3DMakeScale(1.5, 1.5, 1.5);
        circleView.layer.opacity = 0;
    } completion:^(BOOL finished) {
        [circleView removeFromSuperview];
    }];
}
這里是第二種動(dòng)畫的處理代碼,肯定也有改進(jìn)的空間躁劣,希望大家斧正迫吐。
簡(jiǎn)單的來說就是通過傳入的時(shí)間的長短,是圓弧慢慢往外擴(kuò)張账忘,并且同時(shí)慢慢變得透明志膀。

第三種動(dòng)畫則是通過創(chuàng)建5個(gè)顏色是灰色的小圓弧,在創(chuàng)建5個(gè)根據(jù)用戶輸入的顏色的小圓弧闪萄,先把圓弧隱藏梧却。通過用戶傳入的值 0.0 - 1.0 在自行進(jìn)行判斷顯示到哪一級(jí)。由于代碼簡(jiǎn)單且沒什么技術(shù)可言败去,就不貼了
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末圆裕,一起剝皮案震驚了整個(gè)濱河市广鳍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌吓妆,老刑警劉巖赊时,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異行拢,居然都是意外死亡祖秒,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門舟奠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來竭缝,“玉大人,你說我怎么就攤上這事沼瘫√е剑” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵耿戚,是天一觀的道長湿故。 經(jīng)常有香客問我,道長膜蛔,這世上最難降的妖魔是什么坛猪? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮皂股,結(jié)果婚禮上墅茉,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好躁锁,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著卵史,像睡著了一般战转。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上以躯,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天槐秧,我揣著相機(jī)與錄音,去河邊找鬼忧设。 笑死刁标,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的址晕。 我是一名探鬼主播膀懈,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼谨垃!你這毒婦竟也來了启搂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤刘陶,失蹤者是張志新(化名)和其女友劉穎胳赌,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體匙隔,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡疑苫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了纷责。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捍掺。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖碰逸,靈堂內(nèi)的尸體忽然破棺而出乡小,到底是詐尸還是另有隱情,我是刑警寧澤饵史,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布满钟,位于F島的核電站,受9級(jí)特大地震影響胳喷,放射性物質(zhì)發(fā)生泄漏湃番。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一吭露、第九天 我趴在偏房一處隱蔽的房頂上張望吠撮。 院中可真熱鬧,春花似錦讲竿、人聲如沸泥兰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鞋诗。三九已至膀捷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間削彬,已是汗流浹背全庸。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留融痛,地道東北人壶笼。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像雁刷,于是被迫代替她去往敵國和親覆劈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

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