圆形BezierPath填充太多而不是给定的进度值 - iOS Swift

Edo*_*ier 3 cabasicanimation cashapelayer ios uibezierpath swift

我有一个循环的UIBezierPath和2x CAShapeLayers,用于显示我的某个应用程序中特定里程碑的进度.

问题:当我通过CABasicAnimation为进度设置动画时,进度超出了应该做的范围.

上下文:我在milestonesCollectionView中的自定义单元格的子视图中显示此循环视图.

查看层次结构: CollectionView>自定义单元格>子视图> drawRect以在其中创建和添加图层.

我的代码:

定制单元格

在我的自定义单元格中,我设置了currentProgress(现在硬编码用于测试目的)

let placeHolderForProgressView: CircularTrackerView = {
        let ctv = CircularTrackerView()
        ctv.backgroundColor = UIColor.clear
        ctv.translatesAutoresizingMaskIntoConstraints = false
        ctv.currentProgress = 0.5  //set to 0.5 to get a circle filled at 50%
        return ctv
    }()
Run Code Online (Sandbox Code Playgroud)

在CircularTrackerView里面

//每当设置单元格时,我都会为进度设置动画,并将currentProgress提供给progressView

var currentProgress: CGFloat = 0.0 {
        didSet {
            animate(to: currentProgress)
            let percent = Int(currentProgress * 100)
            percentLbl.text = "\(percent)%"
        }
    } 


let shapeLayer = CAShapeLayer() //displays the progress 
let trackLayer = CAShapeLayer() //background of the ring

override func draw(_ rect: CGRect) {
    super.draw(rect)

    let center = CGPoint(x: frame.size.width / 2, y: frame.size.height / 2)
    let circularPath = UIBezierPath(arcCenter: center, radius: frame.size.width / 2, startAngle: -CGFloat.pi / 2, endAngle: 2 * CGFloat.pi, clockwise: true)

    trackLayer.path = circularPath.cgPath
    trackLayer.strokeColor = UIColor.white.withAlphaComponent(0.2).cgColor
    trackLayer.lineWidth = 5
    trackLayer.fillColor = UIColor.clear.cgColor
    trackLayer.lineCap = kCALineCapRound
    layer.addSublayer(trackLayer)

    shapeLayer.path = circularPath.cgPath
    shapeLayer.strokeColor = UIColor.white.cgColor
    shapeLayer.lineWidth = 5
    shapeLayer.strokeEnd = 0
    shapeLayer.fillColor = UIColor.clear.cgColor
    shapeLayer.lineCap = kCALineCapRound
    layer.addSublayer(shapeLayer)

}

private func animate(to progress: CGFloat) {

    let animation = CABasicAnimation(keyPath: "strokeEnd")
    animation.fromValue = 0.0
    animation.toValue = progress
    animation.duration = 2
    animation.fillMode = kCAFillModeForwards
    animation.isRemovedOnCompletion = false

    shapeLayer.add(animation, forKey: "randomString")

}
Run Code Online (Sandbox Code Playgroud)

产量

这个圈子超过了50%......甚至很难我认为我按照正确的步骤创建了这个(稍微改编自YouTube上的LetsBuildThatApp教程:https://www.youtube.com/watch?v = O3ltwjDJaMk )

在此输入图像描述

如果您能提供任何有用的输入,请提前致谢.

luk*_*302 5

问题是你UIBezierPath/你给它的角度:

let circularPath = UIBezierPath(arcCenter: center, radius: frame.size.width / 2, startAngle: -CGFloat.pi / 2, endAngle: 2 * CGFloat.pi, clockwise: true)
Run Code Online (Sandbox Code Playgroud)

所不同的endAngle - startAngle2.5 * PI,但只应2 * PI.当它2.5 * PI意味着您strokeEnd0.5结果1.25 * PI被抚摸.

解决方案,降低了endAngle通过0.5 * PI:

let circularPath = UIBezierPath(arcCenter: center, radius: frame.size.width / 2, startAngle: -0.5 * CGFloat.pi, endAngle: 1.5 * CGFloat.pi, clockwise: true)
Run Code Online (Sandbox Code Playgroud)