CAShapeLayer & UIBezierPath & CABasicAnimation

CAShapeLayer

普通CALayer在被初始化時是需要給一個frame值的,這個frame值一般都與給定view的bounds值一致,它本身是有形狀的,而且是矩形.
每個CAShapeLayer對象都代表著將要被渲染到屏幕上的形狀(shape),CAShapeLayer在初始化時也需要給一個frame值,但是,它本身沒有形狀,它的形狀來源于你給定的一個path,然后它去取CGPath值,它與CALayer有著很大的區別.

并且,系統僅會渲染CAShapeLayer對象的形狀,其他任何非CAShapeLayer的自由屬性在渲染是都會被忽略。因此從某種意義上講CAShapeLayer僅是形狀的容器。雖然由于其實CALayer的子類,可以設置contentsbackgroundColor等屬性,但這些屬性在渲染時也會被忽略。

- 但是,CAShapeLayer提供了自身的可設置性:

path fillColor fillRule strokeColor
strokeStart strokeEnd lineWidth miterLimit
lineCap lineJoin lineDashPhase lineDashPattern
  • path
    動畫路徑,默認為NULL,不支持隱式動畫。路徑可以使用任何的具體子類的動畫CAPropertyAnimation。如果此屬性的值是不為NULL,則path使用指定的路徑,而不是創建該層的合成后的alpha通道。它使用的是非零纏繞規則和當前顏色,不透明度和模糊半徑填充。

  • fillColor
    填充顏色,默認為不透明的黑色,若值為nil,則沒有填充效果。
    fillColor針對于閉合的圖形,對于鏤空圖形只需設置畫筆顏色strokeColor即可。

//閉合多邊形
- (void)drawTriangle {
    UIView *view = [self.view viewWithTag:1026];
    
    CAShapeLayer *triangle = [CAShapeLayer layer];
    triangle.lineWidth = 2;
    triangle.strokeColor = [UIColor clearColor].CGColor;
    triangle.fillColor = [UIColor redColor].CGColor;
    [view.layer addSublayer:triangle];
    
    UIBezierPath *bezierPath = [UIBezierPath bezierPath];
    [bezierPath moveToPoint:CGPointMake(kDeviceWidth/2.0, 50)];
    [bezierPath addLineToPoint:CGPointMake(kDeviceWidth/2.0-100, 150)];
    [bezierPath addLineToPoint:CGPointMake(kDeviceWidth/2.0+100, 150)];
    [bezierPath addLineToPoint:CGPointMake(kDeviceWidth/2.0, 50)];
    
    triangle.path = bezierPath.CGPath;
}
fillColor和strokeColor兩種設置的效果
  • fillRule
    填充規則,默認是kCAFillRuleNonZero。
    kCAFillRuleNonZero:指定非零纏繞規則。計算每個左到右的路徑+1或-1為每個從右到左的道路。如果所有交叉的總和為0,則點是路徑之外,如果該和為非零,改點是在路徑內與包含它的區域被填充。
    kCAFillRuleEvenOdd:指定奇偶纏繞規則。算路徑交叉的總和,如果橫跨的數目是偶數,改點在路徑之外。如果橫跨的數目是奇數,所述點是在路徑內與包含它的區域應被填充。

  • strokeColor
    畫筆顏色。

  • strokeStart
    和strokeEnd組合使用,默認值為1.0,取值范圍0.0~1.0

  • strokeEnd
    和strokeStart組合使用,默認值為1.0,取值范圍為0.0~1.0

  • lineWidth
    線寬。注意線寬有一個特點,線寬從你設置的起點往左右兩邊同時伸展。

  • miterLimit
    斜接樣式,默認值為10.0

  • lineCap
    線端點樣式,默認值為kCALineCapButt,還有kCALineCapRound,kCALineCapSquare


    線端點樣式示例
  • lineJoin
    拐角樣式,默認值為kCALineJoinMiter(尖角),還有kCALineJoinRound(圓角),kCALineJoinBevel(平角)


    拐角樣式示例
  • lineDashPhase
    沖刺階段應用到的形狀的路徑,默認是0.0

  • lineDashPattern
    設置線的樣式,默認為實線,該數組為一個NSNumber數組,數組中的數值依次表示虛線中,單個線的長度,和空白的長度,如:數組@[@10,@5] 表示 有長度為10的線,長度為5的空白,不斷循環后組成的虛線。
    當然數組的長度是不做限制的,你亦可以@[@2,@3,@4,@5],可以表示為長度為2的線+長度為3的空白+長度為4的線+長度為5的空白,不斷循環直到線段結束。

  • mask
    mask本身就是個CALayer,mask屬性用作裁剪功能。
    mask只作為形狀(shape)的樣子,裁剪后的形狀以mask為準,其他例如顏色等屬性以原圖為準。


    兩種mask裁剪示例

- CAShapeLayer有以下幾點特點:

  • 它依附于一個path,必須給予path,即使path不完整也會自動首尾相接。
  • strokeStartstrokeEnd代表著在這個path中所占用的百分比。
  • CAShapeLayer動畫僅限于沿著邊緣的動畫效果,它不能直接實現填充效果,但可以間接實現填充效果。

UIBezierPath

使用UIBezierPath可以創建基于矢量的路徑,此類是Core Graphics框架關于路徑的封裝。使用此類可以定義簡單的形狀,如橢圓、矩形或有多個直線和曲線組成的形狀等。

UIBezierPathCGPathRef數據類型的封裝。如果是基于矢量形狀的路徑,都用直線或曲線去創建。我們使用直線段去創建矩形和多邊形,使用曲線去創建圓弧、圓或其他復雜的曲線形狀。

  • 最基本的初始化方法,用它創建的對象,我們可以根據我們的需要任意定制樣式,可以話任何想畫的圖形。
+ (instancetype)bezierPath;
  • 初始化一個矩形矩形貝塞爾曲線。
+ (instancetype)bezierPathWithRect:(CGRect)rect;
  • 根據一個矩形畫內切曲線,通常用來畫圓或橢圓(取決于傳入的rect是正方形還是長方形)。
+ (instancetype)bezierPathWithOvalInRect:(CGRect)rect;
  • 畫矩形,但是這個矩形可以畫圓角。第一個參數是矩形,第二個參數是圓角大小。
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius;
  • 畫矩形,矩形可以圓角,可以指定某個角或其中多個角成為圓角。參數:UIRectCornerTopLeftUIRectCornerTopRightUIRectCornerBottomLeftUIRectCornerBottomRightUIRectCornerAllCorners
+ (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii;
  • 畫弧線,參數說明:
    • center 弧線中心點的坐標
    • radius 弧線所在圓的半徑
    • startAngle 弧線開始的角度值
    • endAngle 弧線結束的角度值
    • clockwise 是否順時針畫弧線
+ (instancetype)bezierPathWithArcCenter:(CGPoint)center radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle clockwise:(BOOL)clockwise;

CABasicAnimation

CABasicAnimation類的使用方式就是關鍵幀動畫,所謂關鍵幀動畫,就是將Layer的屬性作為keyPath來注冊,指定動畫的起始幀和結束幀,然后自動計算和實現中間的過渡動畫的一種動畫方式。

CABasicAnimation自己只有三個property:

@property(nullable, strong) id fromValue;
@property(nullable, strong) id toValue;
@property(nullable, strong) id byValue

當創建一個CABasicAnimation的時候,需要通過 -setFromValue-setToValue 來指定一個開始值和結束值。當你增加基礎動畫到層中的時候,它開始運行。當用屬性做動畫完成時,例如用位置屬性做動畫,層就會立刻返回到它的初始位置。

- 設定動畫的屬性說明

屬性 說明
duration 動畫時長(單位:秒)
repeatCount 重復次數,永久重復的話設置為HUGE_VALF
beginTime 指定動畫開始時間。從開始指定延遲幾秒執行的話,請設置為「CACurrentMediaTime() + 秒數」的形式
timingFunction 設定動畫的速度變化
autoreverses 動畫結束時是否執行逆動畫
shadowColor 陰影的顏色
shadowOffset 陰影的偏移量
shadowOpacity 陰影的透明度
shadowRadius 陰影的圓角
fromValue 所改變屬性的起始值
toValue 所改變屬性的結束時的值
byValue 所改變屬性相同起始值得改變量 ;

- 常用的animationWithKeyPath值的總結

說明 使用形式
transform.scale 比例轉化 @(0.8)
transform.scale.x 寬的比例 @(0.8)
transform.scale.y 高的比例 @(0.8)
transform.rotation.x 圍繞x軸旋轉 @(M_PI)
transform.rotation.y 圍繞y軸旋轉 @(M_PI)
transform.rotation.z 圍繞z軸旋轉 @(M_PI)
cornerRadius 圓角的設置 @(20)
backgroundColor 背景顏色的變化 [UIColor orangeColor].CGColor;
bounds 大小,中心不變 [NSValue valueWithCGRect:CGRectMake(100,100)];
position 位置(中心點的改變) [NSValue valueWithCGPoint:CGPointMake(100,100)];
contents 內容(比如UIImageView的圖片) imageAnima.toValue = (id)[UIImage imageNamed:@“toIcon”].CGImage;
opacity 透明度 @(0.8)
contentsRect.size.width 橫向拉伸縮放 @(0.5)最好在0~1之間
- 捕獲動畫開始時和終了時的事件

設置委托對象,實現委托方法。

/** 
 * 動畫開始時 
 */
- (void)animationDidStart:(CAAnimation *)theAnimation {
    NSLog(@"begin");  
}  
   
/** 
 * 動畫結束時 
 */  
- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {  
    NSLog(@"end");  
}  

結語

CAShapeLayerUIBezierPath規定一個形狀,CABasicAnimation為其添加動畫。下一篇我將寫具體的實例。最后,非常感謝您閱讀本文。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容