简体   繁体   English

如何将CALayers置于父CALayer内部

[英]How to center CALayers inside parent CALayer

I have an array of UIBezierPaths that I am looping over to create a CALayer. 我遍历了一个UIBezierPaths数组以创建CALayer。 The code to generate the CALayer looks like this: 生成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

As each layer is returned, I am then adding it to a bigger layer ( shapeLayer ) which then gets added to a UIView layer. 返回每个图层后,我将其添加到更大的图层( shapeLayer ),然后将其添加到UIView图层。 (Hopefully that makes sense). (希望这是有道理的)。

The trouble I am having is centering the sublayers (inside the finalShape) that got added while looping. 我遇到的麻烦是使在循环时添加的子层居中(在finalShape内部)。 They obviously have a specific path set using path.cgPath and I don't know how I can achieve this whilst maintaining their position. 他们显然使用path.cgPath设置了特定的路径,我不知道如何在保持位置的同时实现这一目标。 I really (obviously) don't know enough about CALayers to solve this, any help would be greatly appreciated. 我真的(显然)对CALayers并不了解,无法解决此问题,我们将不胜感激。

Thank you. 谢谢。

-- Might be more helpful if I show you the whole code -如果我向您展示整个代码,可能会更有帮助

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
}

If you want to position layers (or views), the point in time at which you do this is crucial. 如果要定位图层(或视图),则执行此操作的时间点至关重要。 For example, if you do this in viewDidLoad , it is too early because the parent layer does not yet have its final size. 例如,如果您在viewDidLoad执行此操作,则为时过早,因为父层尚没有其最终大小。 Also, the size of the parent layer can change, so it is better to center the sublayers whenever the frame of the parent layer has changed. 而且,父层的大小可以更改,因此,只要父层的框架发生更改,最好将子层居中。 You can do this with a subclass of CALayer and overwriting layoutSublayers . 您可以使用CALayer的子类并覆盖layoutSublayers来执行此操作。

It'll look something like this ( not a running example): 看起来像这样( 不是正在运行的示例):

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
            }
        }
    }
}

Note: Your layer has also to layout shapeLayer by 注意:您的layer还必须布局shapeLayer

shapeLayer.frame = layer.bounds

to make this work. 使这项工作。 You can do this by either creating another subclass of CALayer for layer and overriding layoutSublayers() , or (if layer is the layer of a view) overriding layoutSubviews() in your view class. 您可以通过为layer创建CALayer另一个子类并覆盖layoutSublayers()或(如果layer是视图的图层)覆盖视图类中的layoutSubviews()来做到这layoutSubviews() A third option might be overriding layoutSublayers(of:) in the view class, because a UIView is always the delegate of its layer. 第三个选项可能是覆盖视图类中的layoutSublayers(of:) ,因为UIView始终是其层的委托。

But these ways are a bit inelegant, though, so you'd better think about reducing the number of layers in your code. 但是,这些方法有点不太雅致,因此您最好考虑减少代码中的层数。 E. g. 例如 You should try to avoid shapeLayer . 您应该尝试避免shapeLayer

If all of the paths have the same properties, you might use only one CAShapeLayer with the concatenated path, because layers might be very resource intensive. 如果所有路径都具有相同的属性,则可能仅将一个CAShapeLayer与串联路径一起使用,因为图层可能会CAShapeLayer大量资源。

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

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