如何将CALayer居中在父CALayer中

3

我有一个UIBezierPaths数组,我正在循环遍历它来创建CALayer。生成CALayer的代码如下:

Original Answer翻译成"最初的回答"

let layer = CAShapeLayer()
layer.path = path.cgPath
layer.strokeColor = UIColor.gray.cgColor
layer.fillColor = UIColor.clear.cgColor
layer.lineWidth = 3
layer.lineJoin = .bevel
return layer

当每一层返回时,我将其添加到一个更大的图层(shapeLayer),该图层然后添加到UIView图层中。(希望这有意义)。
我遇到的问题是居中循环添加的子图层(在finalShape内)。它们显然使用path.cgPath设置了特定的路径,而我不知道如何在保持它们的位置的同时实现这一点。我对CALayer的了解显然不足以解决这个问题,非常感谢任何帮助。
谢谢。
-- 如果我向您展示整个代码可能会更有帮助
private let shapeLayer = CALayer()

func bind(shape: Shape) {
    let data = NSKeyedUnarchiver.unarchiveObject(with: shape.strokeData)

    guard let paths = data as? [UIBezierPath] else { return }

    for path in paths {
        let guideLine = drawPathLayer(for: path)
        shapeLayer.addSublayer(guideLine)
    }

    layer.addSublayer(shapeLayer)
}

private func drawPathLayer(for path: UIBezierPath) -> CALayer {
    let layer = CAShapeLayer()
    layer.path = path.cgPath
    layer.strokeColor = UIColor.gray.cgColor
    layer.fillColor = UIColor.clear.cgColor
    layer.lineWidth = 3
    layer.lineJoin = .bevel
    return layer
}
1个回答

3
如果您想定位图层(或视图),则在这样做的时间非常重要。例如,如果您在viewDidLoad中执行此操作,则为时过早,因为父图层尚未具有其最终大小。此外,父图层的大小可能会更改,因此最好在父图层的框架已更改时始终将子图层居中。您可以使用CALayer的子类并覆盖layoutSublayers来实现此目的。
代码示例如下(不是可运行的示例):
class CenteringLayer: CALayer {
    override func layoutSublayers() {
        super.layoutSublayers()
        if let theSublayers = sublayers {
            for s in theSublayers {
                var theFrame = s.frame

                theFrame.origin.x = (bounds.width - theFrame.width) / 2.0
                theFrame.origin.y = (bounds.height - theFrame.height) / 2.0
                s.frame = theFrame
            }
        }
    }
}

注意:您的图层还必须通过shapeLayer进行布局。最初的回答。
shapeLayer.frame = layer.bounds

为了使其工作,您可以通过创建另一个CALayer子类来覆盖layerlayoutSublayers()方法,或者(如果layer是视图的层)在您的视图类中覆盖layoutSubviews()方法。第三种选择可能是在视图类中覆盖layoutSublayers(of:),因为UIView始终是其层的委托。

但这些方法有点不太优雅,所以最好考虑减少代码中的层数。例如,您应该尝试避免使用shapeLayer

如果所有路径具有相同的属性,则可以使用仅具有连接路径的一个CAShapeLayer,因为层可能非常资源密集。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接