[英]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.