How can I make a transparent outline for circles so that the background shows through? Like this:

I tried using a mask, but this code does not work ...
Perhaps there are some other solutions?
My code:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let backgroundImage = UIImageView(frame: UIScreen.main.bounds)
backgroundImage.image = UIImage(named: "background")
backgroundImage.contentMode = .scaleAspectFill
view.addSubview(backgroundImage)
view.sendSubviewToBack(backgroundImage)
// Параметры для кругов
let circleSize: CGFloat = 100
let borderWidth: CGFloat = 4
let circleSpacing: CGFloat = 30
var previousCircleView: UIImageView?
for i in 0..<3 {
let circleImageView = UIImageView()
circleImageView.image = UIImage(named: "ggg")
circleImageView.contentMode = .scaleAspectFill
view.addSubview(circleImageView)
let maskLayer = CAShapeLayer()
let circlePath = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: circleSize, height: circleSize))
let borderPath = UIBezierPath(ovalIn: CGRect(x: -borderWidth, y: -borderWidth, width: circleSize + 2 * borderWidth, height: circleSize + 2 * borderWidth))
borderPath.append(circlePath)
borderPath.usesEvenOddFillRule = true
maskLayer.path = borderPath.cgPath
maskLayer.fillRule = .evenOdd
circleImageView.layer.mask = maskLayer
circleImageView.snp.makeConstraints { make in
make.width.height.equalTo(circleSize + 2 * borderWidth)
make.centerY.equalToSuperview()
if let previous = previousCircleView {
make.left.equalTo(previous.snp.right).offset(-(circleSize - circleSpacing + borderWidth))
} else {
make.left.equalToSuperview().offset(20)
}
}
previousCircleView = circleImageView
}
}
}


If your goal is a series of crescents, ending in a full circle, creating a shape layer and a mask will involve drawing part-circle arcs, and some trig.
You could instead do this by creating an image view with the contents you want. In that case, you could write code that runs in a loop, drawing a circle in an opaque color, then switching to clear mode and erasing the outline of the circle. Each new circle will erase part of the previous circle, but the last circle won't be clipped. That's what your sample image shows.
Here is the code I wrote to create that image, loosely based on your starting code:
Here is a sample project on Github that creates the image below: