这对我来说是一个奇怪的问题,在花了两天时间修复它并阅读了我在苹果网站上发现的内容以及堆栈溢出后,我仍然没有解决方案。希望有人可以帮助我。
因此,我正在旋转视图坐标系中的CAShapeLayer。旋转后,将更新框架坐标,但不会更新路径坐标。
在屏幕上,路径和框架都显示为旋转!因此,如果我使用path.contains来查看旋转后某个点是否属于CAShapeLayer,则会得到错误的答案。使用旋转的框架不起作用,因为相邻路径的框架可能会重叠并给出错误的答案。
以下是旋转相关CAShapeLayer的代码:
let shapeCopy = CAShapeLayer()
let inputShape = tempShapeList[index]
shapeCopy.backgroundColor =UIColor.red.withAlphaComponent(0.75).cgColor
shapeCopy.frame = inputShape.frame
shapeCopy.bounds = inputShape.bounds
shapeCopy.path = inputShape.path
shapeCopy.position = inputShape.position
shapeCopy.anchorPoint = inputShape.anchorPoint
print("bounding rect pre rotation: \(shapeCopy.frame)")
print("path pre rotation: \((shapeCopy.path)!)")
let transform = CATransform3DMakeRotation(CGFloat(75*Double.pi/180.0), 0, 0, 1)
shapeCopy.transform = transform
print("bounding rect post rotation:\(shapeCopy.frame)")
print("path post rotation: \((shapeCopy.path)!)")
if ((shapeCopy.path)!.contains(newPoint)) {
containingView.layer.addSublayer(shapeCopy)
answer = index
print("Prize is:\(String(describing: textLabelList[index].text))")
break
}
调试器中的消息:
边界rect预旋转:(139.075809065823,236.846930318145,174.164592138914,163.153069681855)
预旋转路径:路径0x600000236a60:
moveto(207,400)
Lineto(138.901,266.349)
curveto(196.803,236.847)(267.115,247.983)(313.066,293.934)
LINETO(207,400)
封闭路径
边界矩形柱旋转:(189.419925763055,292.163148046286,202.670877072107,210.457199272682)
旋转后的路径:路径0x600000236a60:
moveto(207,400)
Lineto(138.901,266.349)
curveto(196.803,236.847)(267.115,247.983)(313.066,293.934)
LINETO(207,400)
封闭路径
模拟器的ScreenShot:
Screen shot of the simulator 在屏幕快照中,您将看到旋转的路径以及深色派和稍微半透明的框架中的路径框架。
但是路径的坐标没有改变。因此程序认为红点属于旋转掉的阴影切片!如果路径正确更新,则红点将属于标记为“ e6¢”的黄色切片,给出错误的答案。
还请注意,背景命运轮是其自身坐标系中的一个视图等。旋转的暗饼和红点一样,都位于顶层视图的坐标系中。
不确定该帖子是否完全清楚-对此冗长的帖子提前致歉。如果我错过了任何可以帮助您的细节,请告诉我。
提前谢谢。...
答案 0 :(得分:3)
将转换应用于图层不会更改图层内容的存储方式。如果该图层包含图像,则该图像不旋转地存储;如果该图层包含路径,则该路径不旋转地存储。
相反,当窗口服务器构建(“合成”)屏幕图像时,它将在将图层内容绘制到帧缓冲区中时应用转换。
frame
属性是不同的。实际上,它是根据其他几个属性计算得出的:position
,bounds.size
,anchorPoint
和transform
。
您要测试一个点是否在图层路径(即应用了变换的路径)的屏幕外观内。
一种方法是将点转换为图层的坐标系。要转换它,您还需要知道该点的原始坐标系。然后,您可以使用-[CALayer convertPoint:fromLayer]
或-[CALayer convertPoint:toLayer:]
。例如,假设您具有轻击手势识别器,并且想知道轻击是否在路径内:
@IBAction func tapperDidFire(_ tapper: UITapGestureRecognizer) {
let newPoint = tapper.location(in: view)
let newPointInShapeLayer = shapeLayer.convert(newPoint, from: view.layer)
if shapeLayer.path?.contains(newPointInShapeLayer) ?? false {
print("Hit!")
}
}