iOS動畫:Stroke和Path動畫(9)

利用stroke和Path動畫製作下拉刷新動畫。
首先創建一個虛線圓。
image_1

	let ovalShapeLayer = CAShapeLayer()
    ovalShapeLayer.strokeColor = UIColor.white.cgColor//指定path的渲染顏色
    ovalShapeLayer.fillColor = UIColor.clear.cgColor//指定圓填充色
    ovalShapeLayer.lineWidth = 4.0//線寬
    ovalShapeLayer.lineDashPattern = [2, 3]//實線長度2,間隙長度3

    let refreshRadius = frame.size.height/2 * 0.8

    ovalShapeLayer.path = UIBezierPath(ovalIn: CGRect(
      x: frame.size.width/2 - refreshRadius,
      y: frame.size.height/2 - refreshRadius,
      width: 2 * refreshRadius,
      height: 2 * refreshRadius)
      ).cgPath//傳遞path
    layer.addSublayer(ovalShapeLayer)

lineDashPattern:設置邊線的樣式,默認爲實線,傳遞一個NSNumber數組,數組中的數值依次表示虛線中,單個線的長度和空白的長度。
在scrollView滾動時,更改路徑終點的位置,progress表示下拉百分比值:

	ovalShapeLayer.strokeEnd = progress

strokeEnd默認值爲1,strokeStart默認值爲0,起始值和終點值取值範圍爲0-1。
progress爲0.5時,效果如圖:
image_2
現在我們來初始化一架飛機,設置opacity初始值爲0.0。

    let airplaneImage = UIImage(named: "airplane.png")!
    airplaneLayer.contents = airplaneImage.cgImage
    airplaneLayer.bounds = CGRect(x: 0.0, y: 0.0,
                                  width: airplaneImage.size.width,
                                  height: airplaneImage.size.height)
    
    airplaneLayer.position = CGPoint(
        x: frame.size.width/2 + frame.size.height/2 * 0.8,
        y: frame.size.height/2)
    airplaneLayer.opacity = 0.0
    layer.addSublayer(airplaneLayer)

當progress改變時,修改其透明度opacity

	airplaneLayer.opacity = Float(progress)

在開始刷新時,爲strokeStart和strokeEnd添加動畫,讓虛線看起來在轉圈。

    let strokeStartAnimation = CABasicAnimation(
        keyPath: "strokeStart")
    strokeStartAnimation.fromValue = -0.5
    strokeStartAnimation.toValue = 1.0
    
    let strokeEndAnimation = CABasicAnimation(
        keyPath: "strokeEnd")
    strokeEndAnimation.fromValue = 0.0
    strokeEndAnimation.toValue = 1.0
    
    let strokeAnimationGroup = CAAnimationGroup()
    strokeAnimationGroup.duration = 1.5
    strokeAnimationGroup.repeatDuration = 5.0
    strokeAnimationGroup.animations =
        [strokeStartAnimation, strokeEndAnimation]
    ovalShapeLayer.add(strokeAnimationGroup, forKey: nil)

image_3
同時爲飛機添加運動軌跡

    let flightAnimation = CAKeyframeAnimation(keyPath: "position")
    flightAnimation.path = ovalShapeLayer.path
    flightAnimation.calculationMode = kCAAnimationPaced
    
    let airplaneOrientationAnimation = CABasicAnimation(keyPath:
        "transform.rotation")
    airplaneOrientationAnimation.fromValue = 0
    airplaneOrientationAnimation.toValue = 2.0 * .pi
    
    let flightAnimationGroup = CAAnimationGroup()
    flightAnimationGroup.duration = 1.5
    flightAnimationGroup.repeatDuration = 5.0
    flightAnimationGroup.animations = [flightAnimation,
                                       airplaneOrientationAnimation]
    airplaneLayer.add(flightAnimationGroup, forKey: nil)

這裏有一個新的屬性calculationMode計算模式,它有以下取值
kCAAnimationLinear:calculationMode的默認值,表示當關鍵幀爲座標點的時候,關鍵幀之間直接直線相連進行插值計算;
kCAAnimationDiscrete:離散的,就是不進行插值計算,所有關鍵幀直接逐個進行顯示;
kCAAnimationPaced:使得動畫均勻進行,而不是按keyTimes設置的或者按關鍵幀平分時間,此時keyTimes和timingFunctions無效;
kCAAnimationCubic:對關鍵幀爲座標點的關鍵幀進行圓滑曲線相連後插值計算,對於曲線的形狀還可以通過tensionValues,continuityValues,biasValues來進行調整自定義,這裏的數學原理是Kochanek–Bartels spline,這裏的主要目的是使得運行的軌跡變得圓滑;
kCAAnimationCubicPaced:看這個名字就知道和kCAAnimationCubic有一定聯繫,其實就是在kCAAnimationCubic的基礎上使得動畫運行變得均勻,就是系統時間內運動的距離相同,此時keyTimes以及timingFunctions也是無效的。
最後效果如圖:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章