如何在形状图层中居中 CAShapeLayer 路径
How to center the CAShapeLayer path in the shape layer
我创建了一个可以绘图的 DrawView。我创建了一个用于绘图的 UIBezierPath 实例。
// 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
}
问题在于路径(例如图像中的数字 3)未以其 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)
有什么提示吗?谢谢
忘记绘图视图,只考虑如何在已知大小的形状图层中居中路径。这是一个故意的失败:
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)
我们得到这个:
实心圆没有在红色形状图层的中心。好的,我们知道为什么,因为我们知道创建实心圆的贝塞尔曲线路径。但是假设我们不知道。我们仍然可以将形状居中放置在形状图层中,像这样:
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)
结果:
因此,给定一个 CGPath,并给定一个其最终边界已知的形状层,您可以使用该技术使路径在形状层中居中。这些情况完全适用于您的用例。
我创建了一个可以绘图的 DrawView。我创建了一个用于绘图的 UIBezierPath 实例。
// 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
}
问题在于路径(例如图像中的数字 3)未以其 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)
有什么提示吗?谢谢
忘记绘图视图,只考虑如何在已知大小的形状图层中居中路径。这是一个故意的失败:
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)
我们得到这个:
实心圆没有在红色形状图层的中心。好的,我们知道为什么,因为我们知道创建实心圆的贝塞尔曲线路径。但是假设我们不知道。我们仍然可以将形状居中放置在形状图层中,像这样:
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)
结果:
因此,给定一个 CGPath,并给定一个其最终边界已知的形状层,您可以使用该技术使路径在形状层中居中。这些情况完全适用于您的用例。