簡體   English   中英

Swift 3:CAShapeLayer蒙版無法為餅圖動畫制作動畫

[英]Swift 3: CAShapeLayer mask not animating for pie chart animation

我有代碼可以在給定任意輸入數據的情況下成功創建餅圖。 它產生一個餅形圖,如下所示:

餅圖進行動畫處理

我想要的是:

我希望創建一個動畫,以按順序繪制餅圖的這些部分。 也就是說,我希望執行餅圖的“時鍾輕掃”動畫。 屏幕應開始為黑色,然后逐漸填充以產生餅圖的上述圖像。

問題:

我正在嘗試為每個餅圖片段創建一個圖層蒙版,並對圖層蒙版進行動畫處理,以使餅圖片段填充動畫。 但是,當我實現圖層蒙版時,它不會設置動畫,並且屏幕將保持黑色。

編碼:

class GraphView: UIView {
    // Array of colors for graph display
    var colors: [CGColor] = [UIColor.orange.cgColor, UIColor.cyan.cgColor, UIColor.green.cgColor, UIColor.blue.cgColor]

    override func draw(_ rect: CGRect) {
        drawPieChart()
    }

    func drawPieChart() {
        // Get data from file, yields array of numbers that sum to 100
        let data: [String] = getData(from: "pie_chart")

        // Create the pie chart
        let pieCenter: CGPoint = CGPoint(x: frame.width / 2, y: frame.height / 2)
        let radius = frame.width / 3
        let rad = 2 * Double.pi
        var lastEnd: Double = 0
        var start: Double = 0

        for i in 0...data.count - 1 {
            let size = Double(data[i])! / 100
            let end: Double = start + (size * rad)

            // Create the main layer
            let path = UIBezierPath()
            path.move(to: pieCenter)
            path.addArc(withCenter: pieCenter, radius: radius, startAngle: CGFloat(start), endAngle: CGFloat(end), clockwise: true)

            let shapeLayer = CAShapeLayer()
            shapeLayer.path = path.cgPath
            shapeLayer.fillColor = colors[i] 

            // Create the mask
            let maskPath = CGMutablePath()
            maskPath.move(to: pieCenter)
            maskPath.addArc(center: pieCenter, radius: radius, startAngle: CGFloat(start), endAngle: CGFloat(end), clockwise: true)

            let shapeLayerMask = CAShapeLayer()
            shapeLayerMask.path = maskPath
            shapeLayerMask.fillColor = colors[i]
            shapeLayerMask.lineWidth = radius
            shapeLayerMask.strokeStart = 0
            shapeLayerMask.strokeEnd = 1

            // Set the mask
            shapeLayer.mask = shapeLayerMask
            shapeLayer.mask!.frame = shapeLayer.bounds

            // Add the masked layer to the main layer
            self.layer.addSublayer(shapeLayer)

            // Animate the mask
            DispatchQueue.main.asyncAfter(deadline: .now() + Double(i)) {
                let animation = CABasicAnimation(keyPath: "strokeEnd")
                animation.fromValue = shapeLayerMask.strokeStart
                animation.toValue = shapeLayerMask.strokeEnd
                animation.duration = 4
                animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
                animation.isRemovedOnCompletion = false
                animation.autoreverses = false

                shapeLayerMask.add(animation, forKey: nil)
            }

            start = end
        }
    }
}

同樣,此代碼僅產生一個空白屏幕。 如果注釋掉與遮罩相關的代碼並添加shapeLayer作為子視圖,則將看到未設置動畫的餅圖。

我在做錯什么,如何使餅圖進行動畫處理?

必須先將子層添加到父層,然后才能對其進行遮罩:

// Code above this line adds the pie chart slices to the parentLayer
for layer in parentLayer.sublayers! {
    // Code in this block creates and animates a mask for each layer
}
// Add the parent layer to the highest parent view/layer

這就是全部。 您必須確保餅圖切片和子圖層之間存在一對一的對應關系。 這樣做的原因是因為您不能使用一個圖層蒙版的一個實例來蒙版多個視圖/圖層。 執行此操作時,圖層蒙版將成為您要嘗試蒙版的圖層的“ 圖層層次結構 ”的一部分。 必須在蒙版和要蒙版的層之間建立父子關系,才能起作用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM