這篇文章經過使用CAShapeLayer和UIBezierPath來畫出一個動態顯示剩餘流量的小動畫。git
最終實現的效果以下:數組
動態效果圖:bash
實際中,可以用CALayer完成的任務是比較少的,若是使用這個基礎圖層就能實現絕大部分的功能,我們就沒有必要再開啓一個CAShapeLayer了嘛。app
那CAShapeLayer到底有啥子優勢嘛!學習
屬性名 | 做用 |
---|---|
path | 圖像的繪製路徑,path不支持隱式動畫 |
fillColor | 填充path的顏色,或無填充。默認爲不透明黑色。 |
fillRule | 填充path的規則。選項是非零和偶奇。默認爲非零。 |
lineCap | 線端點類型 |
lineDashPattern | 線性模版 |
lineDashPhase | 線型模版的起點 |
lineJoin | 線鏈接類型 |
lineWidth | 線寬 |
miterLimit | 最大斜接長度。 |
strokeColor | 描邊顏色 |
strokeStart | 描邊的起點 |
strokeEnd | 描邊的終點 |
能看到這裏,說明您已經不是一個沒有任何基礎的小白了。因此特別基礎的屬性就不必解釋一遍了。下面只是一個不經常使用或者當即起來稍微費點勁的屬性。動畫
lineDashPattern
: 這是一個NSNumber的數組,索引從1開始記,奇數位數值表示實線長度,偶數位數值表示空白長度。系統會按照數值自動重複設置虛線。miterLimit
:最大斜接長度。斜接長度指的是在兩條線交匯處和外交之間的距離。只有lineJoin屬性爲kCALineJoinMiter時miterLimit纔有效。邊角的角度越小,斜接長度就會越大。爲了不斜接長度過長,咱們可使用miterLimit屬性。若是斜接長度超過miterLimit的值,邊角會以lineJoin的「bevel」即kCALineJoinBevel類型來顯示strokeStart
& strokeEnd
: 描邊的起始點位置。範圍爲0~1.basicLayer.lineDashPattern = [5,2,10,7]複製代碼
這句話的意思是說這個虛線由四部分組成:ui
strokeStart它表示描線開始的地方佔總路徑的百分比。默認值是0。
strokeEnd表示繪製結束的地方站總路徑的百分比。默認值是1,若是小於等於strokeStart 則繪製不出任何內容。spa
手畫一張圖,解釋一下啥意思:.net
作好後的效果以下:3d
fileprivate func hollowLayer(){
// 建立空心的layer
let hollowLayer = CAShapeLayer()
hollowLayer.bounds = CGRect(x: 0, y: 0, width: 100, height: 100)
view.layer.addSublayer(hollowLayer)
hollowLayer.position = view.center
// 最外面待圓角的方形path
let squarePath = UIBezierPath.init(roundedRect: CGRect(x: 0, y: 0, width: 100, height: 100), cornerRadius: 5)
// 中間鏤空的圓形path
let hollowPath = UIBezierPath.init(ovalIn: CGRect(x: 10, y: 10, width: 80, height: 80))
squarePath.append(hollowPath)
hollowLayer.path = squarePath.cgPath
hollowLayer.fillColor = UIColor.lightGray.cgColor
// 設置路徑的填充模式爲兩個圖形的非交集
hollowLayer.fillRule = kCAFillRuleEvenOdd
// 建立進度layer
let processSectorLayer = CAShapeLayer()
view.layer.addSublayer(processSectorLayer)
processSectorLayer.bounds = CGRect(x: 0, y: 0, width: 70, height: 70)
processSectorLayer.position = view.center
// 進度的path
let processSectorPath = UIBezierPath.init(arcCenter: CGPoint.init(x: 35, y: 35), radius: 17.5, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)
processSectorLayer.path = processSectorPath.cgPath
processSectorLayer.lineWidth = 35
// 進度的起點和結束位置,設置進度條修改這個值和結束數值就能夠了
processSectorLayer.strokeStart = 0.5
processSectorLayer.strokeEnd = 0.75
processSectorLayer.strokeColor = UIColor.lightGray.cgColor
processSectorLayer.fillColor = UIColor.clear.cgColor
}複製代碼
有了上面對於CAShapeLayer 的基礎訓練,繪製一個動態的流量圖就不是什麼困難的事情了。
實現後的效果以下:
1,建立一個view,用來展現進度圓環。
2,在進度的view上面添加一個layer,用來展現進度圓環底部灰色的圓環。
3,在灰色的圓環上面,添加一個layer,用來顯示實際的進度。
4,建立一個定時器,定時器用來更新時時進度。
在文章裏面我們只PO出來一些關鍵的代碼,若是想查看源文件,能夠自行下載源碼哈。
// 進度條layer
lazy var circleProgressLayer: CAShapeLayer = {
let circleProgressLayer = CAShapeLayer()
let circleBounds = CGRect(x: 0, y: 0, width: 250, height: 250)
circleProgressLayer.bounds = circleBounds
circleProgressLayer.position = CGPoint(x: circleBounds.width / 2, y: circleBounds.height / 2)
let circleProgressPath = UIBezierPath.init(arcCenter: CGPoint(x: circleBounds.width / 2, y: circleBounds.height / 2), radius: circleBounds.height / 2, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)
circleProgressLayer.strokeStart = 0
circleProgressLayer.strokeEnd = 1
circleProgressLayer.path = circleProgressPath.cgPath
circleProgressLayer.lineWidth = 10
circleProgressLayer.strokeColor = UIColor.init(colorLiteralRed: 0, green: 151, blue: 255, alpha: 1).cgColor
circleProgressLayer.fillColor = UIColor.clear.cgColor
return circleProgressLayer
}()複製代碼
//開啓定時器
timer = Timer.scheduledTimer(timeInterval: 0.04, target: self, selector: #selector(progressShowNumber), userInfo: nil, repeats: true)複製代碼
// 定時器調用的方法
@objc private func progressShowNumber(){
if progressValue > expectValue - 1 && progressValue < expectValue {
timer.invalidate()
circleProgressLayer.strokeEnd = expectValue / 100
progressLabel.text = "\(expectValue)%"
return
}
if progressValue > expectValue {
timer.invalidate()
return
}
//更新進度文字和進度條的strokeEnd
circleProgressLayer.strokeEnd = CGFloat(progressValue) / 100
progressLabel.text = "\(progressValue)%"
progressValue += 1
}複製代碼
這兩天人正好在San Francisco,抽空去San Jose蘋果的大本營溜達溜達。到時候給你們放照哈。
源代碼能夠在這裏下載。git.oschina.net/atypical/mu…
-----------------------華麗分割線,iOS動畫系列全集連接-------------------------------------------------
第一篇:iOS動畫系列之一:經過實戰學習CALayer和透視的原理。作一個帶時分秒指針的時鐘動畫(上)
第二篇:iOS動畫系列之二:經過實戰學習CALayer和透視的原理。作一個帶時分秒指針的時鐘動畫。包含了OC和Swift兩種源代碼(下)
第三篇:iOS動畫系列之三:Core Animation。介紹了Core Animation的經常使用屬性和方法。
第四篇:CABasic Animation。iOS動畫系列之四:基礎動畫之平移篇
第五篇:CABasic Animation。iOS動畫系列之五:基礎動畫之縮放篇&旋轉篇
第六篇:iOS動畫系列之六:利用CABasic Animation完成帶動畫特效的登陸界面
第七篇:iOS動畫系列之七:實現相似Twitter的啓動動畫
第八篇:iOS動畫系列之八:使用CAShapeLayer繪畫動態流量圖
第九篇:iOS動畫系列之九:實現點讚的動畫及播放起伏指示器
第十篇:實戰系列:繪製過山車場景