Swift Can';在将UIView添加到当前UIView后,无法访问子层
我画了一堆现金图层,所以我需要检测我触摸的是哪一个,所以我用这个Swift Can';在将UIView添加到当前UIView后,无法访问子层,swift,uiview,cashapelayer,Swift,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
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(“循环子层”)
p/S:也适用于标签、按钮等。如果在添加UIView
UIButton
后,我打印(self.layer.sublayers为?[CAShapeLayer]),它将返回nil
快速解释:
if let sublayers = self.layer.sublayers as? [CAShapeLayer] {} else {}
当您将self.layer.sublayers作为?[CAShapeLayer],假设所有
self.layer.sublayer
都属于CAShapeLayer
类型。但是,你确定吗,谁告诉你的?还有其他类型的CALayer
,默认组件可能已经附带了一些。这就是它失败的原因。其思想是使用compactMap()
仅保留CAShapeLayer
:
let sublayers = self.layer.sublayers.compactMap { $0 as? [CAShapeLayer] }
详细说明:
if let sublayers = self.layer.sublayers as? [CAShapeLayer] {} else {}
之所以调用
else
,是因为self.layer.sublayers
不能装入,它不是[CAShapeLayer]。在我们的例子中,它们是层,所以这意味着并非所有的子层都是CAShapeLayer
。
因此,让我们只保留CAShapeLayer
,而忘记另一个(CAGradientLayer
,CALayer
,等等)。
为此,我们可以使用compactMap()
闭包逻辑很简单:
数组被迭代。在每次迭代中,该项被称为aSublayer
。我们想做什么就做什么,如果需要,我们返回一个转换后的值,一个Int,等等。
如果不想保留转换后的值,则返回nil,然后将跳过它
由于我们只想保留属于CAShapeLayer
的子层,因此可以对其使用简单的强制转换:
if let aSubLayerAsShapeLayer = aSubLayer as? CAShapeLayer {
return aSubLayerAsShapeLayer
} else { //We won't keep it
return nil
}
这相当于
return aSubLayer as? CAShapeLayer
然后,通过进一步简化(来自单表达式闭包的隐式返回,速记参数名称
,有关的更多信息),我们得到:
此外,由于它“肯定”有一个数组(可能是空的),它不再是可选的,我们将
if let
删除为let
您能检查self.layer.sublayers
是否为空吗?如果不是,则由于演员阵容,您的线路为零。=>let sublayers=self.layer.sublayers.flatMap{$0 as?CAShapeLayer}
?所有子层可能不是一个CAShapeLayer
,而是另一个层?self.layer。子层
不是空的,但当我将其设置为CAShapeLayer时,它返回nil
let sublayers=self.layer.sublayers.flatMap{$0 as?CAShapeLayer}
得到警告从“[CALayer]”到不相关类型“CAShapeLayer”的转换总是失败
,并且还返回nil
“但是当我按照我的建议将其设置为CAShapeLayer时”?因为如果它像你的代码,那么它显然会失败。另外,您添加了一个子视图?但是,形状层在该视图上,而不是在初始视图上?编辑:我的意思是compactMap()
,而不是flatMap()
,我试过,flatMap
,但没有成功。我的新形状层仍在初始形状层上,我刚刚创建了一个新的UIView,没有对它做任何操作。我的意思是compactMap
,而不是flatMap()
,我的错。
let sublayers = self.layer.sublayers.compactMap { $0 as? [CAShapeLayer] }