繁体   English   中英

如何将CALayers置于父CALayer内部

[英]How to center CALayers inside parent CALayer

我遍历了一个UIBezierPaths数组以创建CALayer。 生成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

返回每个图层后,我将其添加到更大的图层( shapeLayer ),然后将其添加到UIView图层。 (希望这是有道理的)。

我遇到的麻烦是使在循环时添加的子层居中(在finalShape内部)。 他们显然使用path.cgPath设置了特定的路径,我不知道如何在保持位置的同时实现这一目标。 我真的(显然)对CALayers并不了解,无法解决此问题,我们将不胜感激。

谢谢。

-如果我向您展示整个代码,可能会更有帮助

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
}

如果要定位图层(或视图),则执行此操作的时间点至关重要。 例如,如果您在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
            }
        }
    }
}

注意:您的layer还必须布局shapeLayer

shapeLayer.frame = layer.bounds

使这项工作。 您可以通过为layer创建CALayer另一个子类并覆盖layoutSublayers()或(如果layer是视图的图层)覆盖视图类中的layoutSubviews()来做到这layoutSubviews() 第三个选项可能是覆盖视图类中的layoutSublayers(of:) ,因为UIView始终是其层的委托。

但是,这些方法有点不太雅致,因此您最好考虑减少代码中的层数。 例如 您应该尝试避免shapeLayer

如果所有路径都具有相同的属性,则可能仅将一个CAShapeLayer与串联路径一起使用,因为图层可能会CAShapeLayer大量资源。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM