将 UIView 添加到当前 UIView 后无法访问子层
Can't access sublayer after adding a UIView into current UIView
我正在绘制一堆 CAShapeLayer,所以我需要检测我正在触摸哪个,所以我使用这个
if let sublayers = self.layer.sublayers as? [CAShapeLayer]{ //get all CAShape and stored as an array
print("loop sublayer")
for layer in sublayers{ // go through each CAShape
print("loop layer")
if let path = layer.path, path.contains(currentPanPoint) { // if there is a path at that point then return, else create a path
print("detecting")
startPointOfTouchedRuler = detectWhichRuler(layer: layer)
if startPointOfTouchedRuler != zeroPoint{
// drawCircle(point: startPointOfTouchedRuler)
break
}else{
}
}
}
}
现在我想在每次创建 CAShapeLayer 时添加一个 UIView 以更轻松地管理和移动它们,我使用它在 CAShapeLayer 位置添加一个新的 Uiview:
func createUIViewOutSideRuler(startPoint:CGPoint, currentPoint:CGPoint, angle: CGFloat){
let viewWidth = distanceFromTwoPoints(startPoint, currentPoint)
print(viewWidth)
let view = UIView(frame: CGRect(x:currentPoint.x, y: currentPoint.y , width: viewWidth, height: dotLineSize * 3))
view.backgroundColor = .orange
view.transform = CGAffineTransform(rotationAngle: angle);
self.addSubview(view)
}
添加新UIview后,获取哪个CAShapeLayer的循环根本不会触发,命令行不打印print("loop sublayer")
P/S:同样适用于Label、Button等。如果我在添加 UIView
UIButton
之后 print(self.layer.sublayers as? [CAShapeLayer])
,它 returns nil
快速解释:
当您执行 self.layer.sublayers as? [CAShapeLayer]
时,您假设所有 self.layer.sublayers
都是 CAShapeLayer
类型。但是,你确定,这是谁告诉你的?还有其他类型的 CALayer
,默认组件可能已经附带了一些。这就是它失败的原因。这个想法是使用 compactMap()
只保留 CAShapeLayer
:
let sublayers = self.layer.sublayers.compactMap { [=10=] as? [CAShapeLayer] }
详细解释:
if let sublayers = self.layer.sublayers as? [CAShapeLayer] {} else {}
else
被调用是因为 self.layer.sublayers
不可装入,它不是 [CAShapeLayer]。在我们的例子中,它们是层,所以这意味着并非所有子层都是 CAShapeLayer
。
所以,让我们只保留 CAShapeLayer
,而忽略另一个(CAGradientLayer
、CALayer
等)。
为此,我们可以使用 compactMap()
.
self.layer.sublayers.compactMap { aSublayer in
}
闭包逻辑很简单:
数组被迭代。在每次迭代中,该项目称为 aSublayer
。我们做任何我们想做的事,如果需要,我们 return 一个转换后的值,一个 Int 等。
如果我们不想保留转换后的值,我们return nil,然后它会被跳过。
因为我们只想保留 CAShapeLayer
的子层,我们可以对它们使用简单的转换:
if let aSubLayerAsShapeLayer = aSubLayer as? CAShapeLayer {
return aSubLayerAsShapeLayer
} else { //We won't keep it
return nil
}
相当于
return aSubLayer as? CAShapeLayer
然后,通过更多的简化(来自 Single-Expression 闭包的隐式 Returns,Shorthand Argument Names
,关于 doc 的更多信息),我们得到:
let sublayers = self.layer.sublayers.compactMap { [=10=] as? [CAShapeLayer] }
此外,由于“确定”有一个数组(可能为空),它不再是可选的,我们将 if let
删除为 let
。
我正在绘制一堆 CAShapeLayer,所以我需要检测我正在触摸哪个,所以我使用这个
if let sublayers = self.layer.sublayers as? [CAShapeLayer]{ //get all CAShape and stored as an array
print("loop sublayer")
for layer in sublayers{ // go through each CAShape
print("loop layer")
if let path = layer.path, path.contains(currentPanPoint) { // if there is a path at that point then return, else create a path
print("detecting")
startPointOfTouchedRuler = detectWhichRuler(layer: layer)
if startPointOfTouchedRuler != zeroPoint{
// drawCircle(point: startPointOfTouchedRuler)
break
}else{
}
}
}
}
现在我想在每次创建 CAShapeLayer 时添加一个 UIView 以更轻松地管理和移动它们,我使用它在 CAShapeLayer 位置添加一个新的 Uiview:
func createUIViewOutSideRuler(startPoint:CGPoint, currentPoint:CGPoint, angle: CGFloat){
let viewWidth = distanceFromTwoPoints(startPoint, currentPoint)
print(viewWidth)
let view = UIView(frame: CGRect(x:currentPoint.x, y: currentPoint.y , width: viewWidth, height: dotLineSize * 3))
view.backgroundColor = .orange
view.transform = CGAffineTransform(rotationAngle: angle);
self.addSubview(view)
}
添加新UIview后,获取哪个CAShapeLayer的循环根本不会触发,命令行不打印print("loop sublayer")
P/S:同样适用于Label、Button等。如果我在添加 UIView
UIButton
之后 print(self.layer.sublayers as? [CAShapeLayer])
,它 returns nil
快速解释:
当您执行 self.layer.sublayers as? [CAShapeLayer]
时,您假设所有 self.layer.sublayers
都是 CAShapeLayer
类型。但是,你确定,这是谁告诉你的?还有其他类型的 CALayer
,默认组件可能已经附带了一些。这就是它失败的原因。这个想法是使用 compactMap()
只保留 CAShapeLayer
:
let sublayers = self.layer.sublayers.compactMap { [=10=] as? [CAShapeLayer] }
详细解释:
if let sublayers = self.layer.sublayers as? [CAShapeLayer] {} else {}
else
被调用是因为 self.layer.sublayers
不可装入,它不是 [CAShapeLayer]。在我们的例子中,它们是层,所以这意味着并非所有子层都是 CAShapeLayer
。
所以,让我们只保留 CAShapeLayer
,而忽略另一个(CAGradientLayer
、CALayer
等)。
为此,我们可以使用 compactMap()
.
self.layer.sublayers.compactMap { aSublayer in
}
闭包逻辑很简单:
数组被迭代。在每次迭代中,该项目称为 aSublayer
。我们做任何我们想做的事,如果需要,我们 return 一个转换后的值,一个 Int 等。
如果我们不想保留转换后的值,我们return nil,然后它会被跳过。
因为我们只想保留 CAShapeLayer
的子层,我们可以对它们使用简单的转换:
if let aSubLayerAsShapeLayer = aSubLayer as? CAShapeLayer {
return aSubLayerAsShapeLayer
} else { //We won't keep it
return nil
}
相当于
return aSubLayer as? CAShapeLayer
然后,通过更多的简化(来自 Single-Expression 闭包的隐式 Returns,Shorthand Argument Names
,关于 doc 的更多信息),我们得到:
let sublayers = self.layer.sublayers.compactMap { [=10=] as? [CAShapeLayer] }
此外,由于“确定”有一个数组(可能为空),它不再是可选的,我们将 if let
删除为 let
。