I created a DrawView where it's possible to draw. I created an instance of UIBezierPath for drawing.
// This function is called when the user has finished drawing.
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
let shapeLayer = CAShapeLayer()
//The CAShapeLayer has the same path of the drawing (currentPath is the instance of UIBezierPath).
shapeLayer.path = currentPath?.cgPath
shapeLayer.strokeColor = UIColor.black.cgColor
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.lineWidth = 10.0
//Here I set the shapeLayer on the drawingView (the blue one that you can see in the image)
drawingView.layer.addSublayer(shapeLayer)
shapeLayer.position = CGPoint(x: drawingView.layer.bounds.midX, y: drawingView.layer.bounds.midY)
shapeLayer.backgroundColor = UIColor.blue.cgColor
shapeLayer.frame = drawingView.layer.bounds
}
The problem is that the path (e.g number 3 in the image) is not centered on its shapeLayer.
shapeLayer.path?.boundingBoxOfPath = (289.5, 349.5, 525.0, 129.0)
shapeLayer.frame = (0.0, 0.0, 200.0, 200.0)
shapeLayer.position = (100.0, 100.0)
drawingView.frame = (0.0, 912.0, 200.0, 200.0)
Any hint? thank you
Forget the drawing view and just think about how to center a path in a shape layer of known size. Here's a deliberate failure:
let path = UIBezierPath(ovalIn: CGRect(x: 50, y: 50, width: 50, height: 50))
let lay = CAShapeLayer()
lay.frame = CGRect(x: 40, y: 40, width: 200, height: 200)
lay.backgroundColor = UIColor.red.cgColor
lay.path = path.cgPath
self.view.layer.addSublayer(lay)
We get this:
The filled circle is not centered in the red shape layer. Okay, we know why, because we know the bezier path that created the filled circle. But let's say we don't know that. We can still center the shape in the shape layer, like this:
let path = UIBezierPath(ovalIn: CGRect(x: 50, y: 50, width: 50, height: 50))
let lay = CAShapeLayer()
lay.frame = CGRect(x: 40, y: 40, width: 200, height: 200)
lay.backgroundColor = UIColor.red.cgColor
let cgpath = path.cgPath
let box = cgpath.boundingBoxOfPath
let xtarget = (lay.bounds.width - box.width)/2
let ytarget = (lay.bounds.height - box.height)/2
let xoffset = xtarget - box.minX
let yoffset = ytarget - box.minY
var transform = CGAffineTransform(translationX: xoffset, y: yoffset)
let cgpath2 = cgpath.copy(using: &transform)
lay.path = cgpath2
self.view.layer.addSublayer(lay)
Result:
So, given a CGPath, and given a shape layer whose final bounds are known, you can use that technique to center the path in the shape layer. And those are circumstances that apply perfectly to your use case.