2017-06-08 104 views
0

我試圖從某個開始角度到某個結束角度實施弧形繪製。我正在嘗試繪製弧形圖,但沒有運氣。iOS Swift - 弧形填充的動畫繪製,不是邊框筆劃

我已經找了幾個實現,但他們都指的是圈的動畫boder繪圖。

像繪製一個餡餅,但與一種顏色。有一定的開始和結束角度。餡餅的動畫。

我喜歡的是在從起始角度到結束角度動畫弧時有動畫填充。

像弧一樣正在順時針繪製,並在繪製時填充其內部顏色。

任何想法我如何在Swift中實現這一點?

在此先感謝。

編輯

這是我得出:

(灰色表示通過繪製餅覆蓋的區域)

enter image description here

代碼繪製餅圖

import Foundation 
import UIKit 

@IBDesignable class PieChart : UIView { 

    @IBInspectable var percentage: CGFloat = 50 { 
     didSet { 
      self.setNeedsDisplay() 
     } 
    } 

    @IBInspectable var outerBorderWidth: CGFloat = 2 { 
     didSet { 
      self.setNeedsDisplay() 
     } 
    } 

    @IBInspectable var outerBorderColor: UIColor = UIColor.white { 
     didSet { 
      self.setNeedsDisplay() 
     } 
    } 

    @IBInspectable var percentageFilledColor: UIColor = UIColor.primary { 
     didSet { 
      self.setNeedsDisplay() 
     } 
    } 

    let circleLayer = CAShapeLayer() 

    override func draw(_ rect: CGRect) { 
     drawPie(rect: rect, endPercent: percentage, color: UIColor.primary) 
    } 

    func drawPie(rect: CGRect, endPercent: CGFloat = 70, color: UIColor) { 
     let center = CGPoint(x: rect.origin.x + rect.width/2, y: rect.origin.y + rect.height/2) 
     let radius = min(rect.width, rect.height)/2 

     let gpath = UIBezierPath(arcCenter: center, radius: radius, startAngle: 0, endAngle: CGFloat(360.degreesToRadians), clockwise: true) 
     UIColor.white.setFill() 
     gpath.fill() 

     let circlePath = UIBezierPath(arcCenter: center, radius: radius, startAngle: CGFloat(0), endAngle:CGFloat(360.degreesToRadians), clockwise: true) 

     circleLayer.path = circlePath.cgPath 

     circleLayer.fillColor = UIColor.clear.cgColor 
     circleLayer.strokeColor = outerBorderColor.cgColor 
     circleLayer.lineWidth = outerBorderWidth 
     circleLayer.borderColor = outerBorderColor.cgColor 

     self.layer.addSublayer(circleLayer) 

     let π: CGFloat = 3.14 

     let halfPi: CGFloat = π/2 

     let startPercent: CGFloat = 0.0 

     let startAngle = (startPercent/100 * π * 2 - π) + halfPi 
     let endAngle = (endPercent/100 * π * 2 - π) + halfPi 

     let path = UIBezierPath() 
     path.move(to: center) 
     path.addArc(withCenter: center, radius: radius, startAngle: CGFloat(startAngle), endAngle: CGFloat(endAngle), clockwise: true) 
     path.close() 
     percentageFilledColor.setFill() 
     path.fill() 
    } 
} 
+0

創建UIView的子類,以便您可以繪製特定程度的餅圖。 –

+0

@ElTomato請參閱編輯。 –

+0

PieChart需要一個具有結束角度值的初始化程序,以便它可以被初始化。然後創建另一個類來創建PieChart對象,並逐漸更改結束值。 –

回答

0

我已經使用操場和swift創建了這段代碼。這段代碼將繪製一個餅圖來填充顏色。確保在Xcode上打開時間線窗格以查看動畫的工作情況。我無法找到將路徑函數直接傳遞給CAAnimation的方法,所以我的解決方法是創建一個步驟列表,每個步驟都包含百分比舞臺的路徑。您可以更改窒息動畫的步驟。

//: Playground - noun: a place where people can play 

import UIKit 
import XCPlayground 

let STEPS_ANIMATION = 50 

let initialPercentage : CGFloat = 0.10 
let finalPercentage : CGFloat = 0.75 


func buildPiePath(frame : CGRect, percentage : CGFloat) -> UIBezierPath { 

    let newPath = UIBezierPath() 

    let startPoint = CGPoint(x: frame.size.width, y: frame.height/2.0) 
    let centerPoint = CGPoint(x: frame.size.width/2.0, y: frame.height/2.0) 
    let startAngle : CGFloat = 0 
    let endAngle : CGFloat = percentage * 2 * CGFloat(M_PI) 

    newPath.move(to: centerPoint) 
    newPath.addLine(to: startPoint) 
    newPath.addArc(withCenter: centerPoint, 
        radius: frame.size.width/2.0, 
        startAngle: startAngle, 
        endAngle: endAngle, 
        clockwise: true) 
    newPath.addLine(to: centerPoint) 
    newPath.close() 
    return newPath 
} 

func buildPiePathList(frame: CGRect, 
         startPercentage: CGFloat, 
         finalPercentage: CGFloat) -> [AnyObject] { 

    var listValues = [AnyObject]() 

    for index in 1...STEPS_ANIMATION { 

     let delta = finalPercentage - startPercentage 
     let currentPercentage = CGFloat(index)/CGFloat(STEPS_ANIMATION) 

     let percentage = CGFloat(startPercentage + (delta * currentPercentage)) 
     listValues.append(buildPiePath(frame: frame, 
             percentage: percentage) 
      .cgPath) 

    } 

    return listValues 
} 




// Container for pie chart 

let container = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 400)) 
container.backgroundColor = UIColor.gray 
XCPShowView(identifier: "Container View", view: container) 

let circleFrame = CGRect(x: 20, y: 20, width: 360, height: 360) 



// Red background 
let background = CAShapeLayer() 
background.frame = circleFrame 
background.fillColor = UIColor.red.cgColor 
background.path = buildPiePath(frame: circleFrame, percentage: 1.0).cgPath 

container.layer.addSublayer(background) 




// Green foreground that animates 
let foreground = CAShapeLayer() 
foreground.frame = circleFrame 
foreground.fillColor = UIColor.green.cgColor 
foreground.path = buildPiePath(frame: circleFrame, percentage: initialPercentage).cgPath 

container.layer.addSublayer(foreground) 




// Filling animation 
let fillAnimation = CAKeyframeAnimation(keyPath: "path") 
fillAnimation.values = buildPiePathList(frame: circleFrame, 
             startPercentage: initialPercentage, 
             finalPercentage: finalPercentage) 
fillAnimation.duration = 3 
fillAnimation.calculationMode = kCAAnimationDiscrete 
foreground.add(fillAnimation, forKey:nil)