ios - 圆形 BezierPath 相对于给定的进度值填充太多 - iOS Swift

标签 ios swift uibezierpath cashapelayer cabasicanimation

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

问题:当我通过 CABasicAnimation 为进度设置动画时,进度超出了它应该做的事情。

上下文: 我在 milestonesCollectionView 内的自定义单元格的 subview 中显示此 circularView。

View Hierarchy:CollectionView > Custom Cell > subview > 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
    }()

内部 CircularTrackerView

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

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")

}

输出

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

enter image description here

如果您能提供任何有用的意见,请提前致谢。

最佳答案

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

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

endAngle - startAngle 的区别是 2.5 * PI 但应该仅为 2 * PI。当它是 2.5 * PI 时,这意味着 0.5strokeEnd 导致 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)

关于ios - 圆形 BezierPath 相对于给定的进度值填充太多 - iOS Swift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48852681/

相关文章:

ios - SKView 到 UIView

ios - 我的自定义形状后面的颜色已填充,我想将其设为白色

ios - 将图像与顶部对齐,在 Swift 2 iOS 9 中显示图像的一部分

ios - Xcode 7 Swift 2 对象大小在运行时不同

iphone - iCarousel 的索引

swift - 参数类型 'Int' 不符合预期类型 'NSCoding & NSCopying & NSObjectProtocol'

ios - Swift 4 中的文本到语音转换

ios - swift 中的 UIActionSheet 将取消按钮放在 iOS 7 的顶部

sprite-kit - SKScene 中的绘制矩形

ios - 检测用户触摸移动方向?