Swift 使用重新绘制刷新饼图

Swift 使用重新绘制刷新饼图,swift,drawrect,Swift,Drawrect,我有一个饼图视图,下面是完整的代码 private(set) var animationTime: [CFTimeInterval] = [1, 1, 1] private(set) var values: [Double] = [0, 0, 0] private(set) var colors: [UIColor] = [UIColor.red, UIColor.blue, UIColor.yellow] private(set) var radiusRatios: [D

我有一个饼图视图,下面是完整的代码

  private(set) var animationTime: [CFTimeInterval] = [1, 1, 1]
   private(set) var values: [Double] = [0, 0, 0]
   private(set) var colors: [UIColor] = [UIColor.red, UIColor.blue, UIColor.yellow]
   private(set) var radiusRatios: [Double] = [1, 1, 1]
     
     
   private(set) var dataSize: Int {
      get {
         return values.count
      }
      set {
         while animationTime.count > newValue {
            animationTime.removeLast()
         }
         while animationTime.count < newValue {
            animationTime.append(1)
         }
         
         while values.count > newValue {
            values.removeLast()
         }
         while values.count < newValue {
            values.append(1)
         }
         
         while colors.count > newValue {
            colors.removeLast()
         }
         while colors.count < newValue {
            colors.append(UIColor.red)
         }
         
         while radiusRatios.count > newValue {
            radiusRatios.removeLast()
         }
         while radiusRatios.count < newValue {
            radiusRatios.append(1)
         }
      }
   }
   
   func setCircle(number index: Int, data: Double) {
      values[index] = data
   }
     

   var drawing = false
   
   var animationOption = UIView.AnimationOptions()
   
   var maximumAnimationDuration: TimeInterval = 0
     
   override public func draw(_ rect: CGRect) {

       if !drawing {
             
           drawing = true
            
            
            
                     var dataInPercentage = [Double]()
                     var max = Double(0)
                     for value in values {
                        max += value
                     }
                     for value in values {
                        dataInPercentage.append(value / max)
                     }
            
                     layer.sublayers?.removeAll()
                     layer.mask?.removeAllAnimations()
            
                     var startAngle = CGFloat(0)
                     var endAngle = CGFloat(0)
                     for index in 0 ..< dataSize {
                        endAngle = startAngle + CGFloat(dataInPercentage[index] * 2) * CGFloat.pi
               
                        let circle = CAShapeLayer()
                        layer.addSublayer(circle)
                        circle.position = CGPoint(x: layer.bounds.minX, y: layer.bounds.midY)
                        let circleCenter = CGPoint(x: 0, y: rect.width / 2)
               
                        let circularPath = UIBezierPath()
                        circularPath.move(to: circleCenter)
                        circularPath.addArc(withCenter: circleCenter, radius: CGFloat(radiusRatios[index]) * rect.width / 2, startAngle: startAngle, endAngle: endAngle, clockwise: true)
                        startAngle = endAngle
                        circularPath.close()
               
                        circle.path = circularPath.cgPath
               
                        circle.strokeColor = UIColor.gray.cgColor // edited
                        circle.lineWidth = 1
                        circle.lineJoin = .round
                        circle.fillColor = colors[index].cgColor
                        circle.transform = CATransform3DMakeRotation(-CGFloat.pi / 2, 0, 0, 1)
                     }
                     let maskLayer = CAShapeLayer()
                     let coverPath = UIBezierPath(roundedRect: rect, cornerRadius: rect.width / 2)
                     maskLayer.path = coverPath.cgPath
                     maskLayer.strokeEnd = 0
                     maskLayer.frame = rect
                     maskLayer.fillColor = UIColor.clear.cgColor
                     maskLayer.strokeColor = UIColor.gray.cgColor // edited
                     maskLayer.lineWidth = rect.width
            
                     centerPieCircleheight = rect.height
                     centerPieCircleWidth = rect.width
            
                     layer.mask = maskLayer
            
                     let animation = CABasicAnimation(keyPath: "strokeEnd")
                     animation.duration = 1
                     animation.fromValue = 0.0
                     animation.toValue = 1.0
                     animation.fillMode = CAMediaTimingFillMode.forwards
                     animation.isRemovedOnCompletion = false
                     maskLayer.add(animation, forKey: "PieChartOverlayer")
            
                     UIView.transition(with: self,
                                       duration: animation.duration,
                                       options: animationOption,
                                       animations: nil,
                                       completion: { [weak self] _ in
                                          self?.drawing = false
                                       })
             
             }
        }
而不是在其父控制器中添加值:

   public func setValues(number: Int, data: Double) {
      activityChart.setNeedsDisplay()
      activityChart.setCircle(number: number, data: data)
   }
     
如你所知,我必须使用
setNeedsDisplay
在新值出现时刷新图表,但当我这样做时,整个图表将再次顺时针绘制,这是不好的,尤其是当图表应该每隔几秒钟刷新一次时

谁能给我一个方法来管理它,显示新的数据,而不需要再次绘制动画(我更喜欢那样),甚至不需要动画


非常感谢

有什么建议吗?
   public func setValues(number: Int, data: Double) {
      activityChart.setNeedsDisplay()
      activityChart.setCircle(number: number, data: data)
   }