iOS (Swift) CAShapeLayer 的环形 UIBezierPath

iOS (Swift) Annuls-shaped UIBezierPath for CAShapeLayer

我正在尝试制作一个环形 UIBezierPath 用作 CAShapeLayer

path

以下生成一个循环路径:

let radius = 100.0
let circularPath = UIBezierPath(arcCenter: .zero, radius: radius, startAngle: 0.0, endAngle: 2.0 * .pi, clockwise: true)

let layer = CAShapeLayer()
layer.path = circularPath.cgPath

但是,我想要一个填充在 radiusouterRadius = radius + 10 之间的环形 UIBezierPath

如果这就是您想要的("Annulus" 形状):

您可以通过创建椭圆路径并附加更小的椭圆路径来实现。

您可以直接在 Playground 页面中 运行 获得该结果:

import PlaygroundSupport
import UIKit

class AnnulusView: UIView {

    private var annulusLayer: CAShapeLayer!
    private var annulusWidth: CGFloat = 10.0
    private var fillColor: UIColor = .red

    override func layoutSubviews() {
        super.layoutSubviews()

        if annulusLayer == nil {
            annulusLayer = CAShapeLayer()
            layer.addSublayer(annulusLayer)
        }

        let r = bounds
        let outerPath = UIBezierPath(ovalIn: r)
        let innerPath = UIBezierPath(ovalIn: r.insetBy(dx: annulusWidth, dy:annulusWidth))
        outerPath.append(innerPath)
        outerPath.usesEvenOddFillRule = true

        annulusLayer.path = outerPath.cgPath
        annulusLayer.fillRule = kCAFillRuleEvenOdd
        annulusLayer.fillColor = fillColor.cgColor

        // if you want a border
//      annulusLayer.lineWidth = 1
//      annulusLayer.strokeColor = UIColor.black.cgColor
    }

}

class TestingViewController: UIViewController {

    override public var preferredContentSize: CGSize {
        get { return CGSize(width: 400, height: 400) }
        set { super.preferredContentSize = newValue }
    }

    var theAnnulusView: AnnulusView = {
        let v = AnnulusView()
        v.translatesAutoresizingMaskIntoConstraints = false
        return v
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .white

        view.addSubview(theAnnulusView)

        // make the Annulus view 100x100 centered in this view
        NSLayoutConstraint.activate([
            theAnnulusView.widthAnchor.constraint(equalToConstant: 100),
            theAnnulusView.heightAnchor.constraint(equalToConstant: 100),
            theAnnulusView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            theAnnulusView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            ])

    }

}

let viewController = TestingViewController()

PlaygroundPage.current.liveView = viewController

看看这个,可能会有帮助。 如果需要整圈,需要调整arcCenter

let width:CGFloat = 10
let radius:CGFloat = 100.0-width/2
let circularPath = UIBezierPath(arcCenter: .zero, radius: radius, startAngle: 0.0, endAngle: 2.0 * .pi, clockwise: true)

let layer = CAShapeLayer()
layer.lineWidth = width
layer.path = circularPath.cgPath