先看效果圖
要想完成上面顯示的效果要用到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)畫:
- 都包含一個(gè)小話筒
- 小話筒可以是實(shí)心的或者飛實(shí)心
- 包含標(biāo)題
- 都有一個(gè)半透明的灰色背景
小話筒 作者這里把話筒看成了4糕韧、5個(gè)部分枫振。
- 一個(gè)圓角長方形的邊框 (通過設(shè)置 fillColor 和 strokeColor)
- 一個(gè)圓角長方形的矩形 (通過設(shè)置 fillColor 和 strokeColor,這里只有在是第一種動(dòng)畫效果的時(shí)候才需要設(shè)置)
- 一個(gè)圓弧
- 一個(gè)連接圓弧的小圓角矩形 (垂直方向)
- 一個(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ù)可言败去,就不貼了
- demo網(wǎng)址https://github.com/codepgq/PQVoiceInputView.git
喜歡的希望可以star一下放航,多謝。