UIBezierPath 绘制矩形以及所需的圆

UIBezierPath draws rect along with the required circle

我正在尝试使用 UIBezierPath(rect:) 构造函数绘制圆,但是连同圆 - 矩形形状也被绘制为框架并且可见。这是我的代码:

class ProgressView: UIView {
let progressLayer = CustomShapeLayer()//declared below this class
override init(frame: CGRect) {
    super.init(frame: frame)
    self.isOpaque = false
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)

}
override func draw(_ rect: CGRect) {
    let bounds = self.layer.bounds
    let centerX = bounds.midX
    let centerY = bounds.midY

    let upperCenterPoint = CGPoint(x: centerX, y: (centerY))
    let arcPathStartAngle: CGFloat = 2 * .pi
    let arcPathEndAngle: CGFloat = 0.0
    let radius: CGFloat = bounds.size.width / 3

    print(centerX, centerY, radius, "dim")

    let strokeWidth: CGFloat = 1//to show rect being formed
    let arcPath = UIBezierPath(rect: bounds.insetBy(dx: -strokeWidth, dy: -strokeWidth))

    arcPath.move(to: CGPoint(x: centerX + radius, y: centerY))
    arcPath.addArc(withCenter: upperCenterPoint, radius: radius, startAngle: arcPathStartAngle, endAngle: arcPathEndAngle, clockwise: false)
    arcPath.close()

    progressLayer.strokeColor = UIColor.white.cgColor
    progressLayer.path = arcPath.cgPath
    self.layer.addSublayer(progressLayer)

    let animateStrokeEnd = CABasicAnimation(keyPath: "strokeEnd")
    animateStrokeEnd.duration = 2.0
    animateStrokeEnd.fromValue = 0.0
    animateStrokeEnd.toValue = 1.0

    progressLayer.add(animateStrokeEnd, forKey: "animate stroke end animation")
}
}

//subclassing
class CustomShapeLayer: CAShapeLayer {
override init() {
    super.init()

    self.fillColor = UIColor.clear.cgColor
    self.lineWidth = CGFloat(5*Double.pi)
    self.lineCap = kCALineCapRound
}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}
}

我不需要将矩形绘制为框架,我是否只需要使用 UIBezierPath 空构造函数(因为它可以达到目的),并且不能使用 UIBezierPath(rect:) 构造函数吗?

为这个替换贝塞尔曲线路径初始化 let arcPath = UIBezierPath() 你的问题是你正在使用 UIBezierPath(rect: 进行初始化,它创建了一个矩形路径,正如你在这张图片中看到的那样

完整绘制方法代码

override func draw(_ rect: CGRect) {
    let bounds = self.layer.bounds
    let centerX = bounds.midX
    let centerY = bounds.midY

    let upperCenterPoint = CGPoint(x: centerX, y: (centerY))
    let arcPathStartAngle: CGFloat = 2 * .pi
    let arcPathEndAngle: CGFloat = 0.0
    let radius: CGFloat = bounds.size.width / 3

    print(centerX, centerY, radius, "dim")

    let strokeWidth: CGFloat = 1//to show rect being formed
    let arcPath = UIBezierPath()
    arcPath.move(to: CGPoint(x: centerX + radius, y: centerY))
    arcPath.addArc(withCenter: upperCenterPoint, radius: radius, startAngle: arcPathStartAngle, endAngle: arcPathEndAngle, clockwise: false)
    arcPath.close()

    progressLayer.strokeColor = UIColor.white.cgColor
    progressLayer.path = arcPath.cgPath
    self.layer.addSublayer(progressLayer)

    let animateStrokeEnd = CABasicAnimation(keyPath: "strokeEnd")
    animateStrokeEnd.duration = 2.0
    animateStrokeEnd.fromValue = 0.0
    animateStrokeEnd.toValue = 1.0

    progressLayer.add(animateStrokeEnd, forKey: "animate stroke end animation")
}

试试这个 导入 UIKit

class CircularProgressBar: UIView {

let shapeLayer       = CAShapeLayer()
let secondShapeLayer = CAShapeLayer()
var circularPath: UIBezierPath?

override init(frame: CGRect) {
    super.init(frame: frame)
    print("Frame: \(self.frame)")
    makeCircle()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    makeCircle()
}

func makeCircle(){
    let circularPath = UIBezierPath(arcCenter: .zero, radius: self.bounds.width / 2, startAngle: 0, endAngle: 2 * CGFloat.pi, clockwise: true)
    shapeLayer.path = circularPath.cgPath
    shapeLayer.strokeColor = UIColor.orange.cgColor//UIColor.init(red: 0.0/255.0, green: 0.0/255.0, blue: 0.0/255.0, alpha: 1.0).cgColor
    shapeLayer.lineWidth = 5.0
    shapeLayer.fillColor = UIColor.clear.cgColor
    shapeLayer.lineCap = kCALineCapRound
    shapeLayer.strokeEnd = 0
    shapeLayer.position = self.center
    shapeLayer.transform = CATransform3DRotate(CATransform3DIdentity, -CGFloat.pi / 2, 0, 0, 1)
    self.layer.addSublayer(shapeLayer)

}


func showProgress(percent: Float){
    shapeLayer.strokeEnd = CGFloat(percent/100)
}
}