UIView
具有在坐标空间之间转换点、矩形等的功能。我需要为 UIBezierPaths
做同样的事情。作为说明,考虑两个视图,viewA
和 viewB
。我们在 rectA : CGRect
的坐标空间中有 viewA
。我们可以计算一下:
let rectB = viewB.convert(rectA, from:viewA)
现在假设我们从矩形创建一条路径:
let pathA = UIBezierPath(rect: rectA)
问题是,如何计算
rectB
。我们可以简单地:
let pathB = UIBezierPath(rect: rectB)
但只有当我们有
rectB
时,这才有效。如果我们只有“pathA”怎么办?
我认为要做到这一点,我们需要进行转换
aTob
。然后我们可以做:
var pathB = pathA
pathB.apply(aTob)
所以问题归结为如何计算
aTob
。为简单起见,假设没有旋转。
根据结果,在
pathA
中绘制 viewA
应在屏幕上绘制与在 pathB
中绘制 viewB
相同形状和位置的路径。
apply()
。
您可以通过将
viewB
的原点转换为viewA
的坐标空间来计算变换所需的x和y。
这里有一些示例代码,您可以将其放入 Swift Playground:
// Some setup
let rectA = CGRect(x: 40, y: 60, width: 200, height: 100)
let rectB = CGRect(x: 10, y: 80, width: 200, height: 100)
let viewA = UIView(frame: rectA)
let viewB = UIView(frame: rectB)
// Create pathA
let pathA = UIBezierPath(rect: rectA)
// Calculate the offset needed to move from viewA to viewB
let offset = viewA.convert(CGPoint.zero, from: viewB)
let tranform = CGAffineTransform(translationX: offset.x, y: offset.y)
// Copy pathA
let pathB = UIBezierPath()
pathB.append(pathA)
// Shift pathB
pathB.apply(tranform)
// Check result
print(pathA)
print(pathB)
输出:
<UIBezierPath: 0x600002c31e80; <MoveTo {40, 60}>,
<LineTo {140, 60}>,
<LineTo {140, 160}>,
<LineTo {40, 160}>,
<Close>
<UIBezierPath: 0x600002c12280; <MoveTo {10, 80}>,
<LineTo {110, 80}>,
<LineTo {110, 180}>,
<LineTo {10, 180}>,
<Close>
我相信这就是您正在寻找的。
offset
的计算可能会倒退。如果 pathB
的结果方向错误,请将 offset
行更改为:
let offset = viewB.convert(CGPoint.zero, from: viewA)
这是
UIView
的扩展,用于将 UIBezierPath
从一个视图转换为另一个视图/从另一个视图转换:
extension UIView {
private func adjust(_ path: UIBezierPath, by offset: CGPoint) -> UIBezierPath {
let transform = CGAffineTransform(translationX: offset.x, y: offset.y)
let result = UIBezierPath()
result.append(path)
result.apply(tranform)
return result
}
func convert(_ path: UIBezierPath, from view: UIView) -> UIBezierPath {
let offset = convert(CGPoint.zero, from: view)
return adjust(path, by: offset)
}
func convert(_ path: UIBezierPath, to view: UIView) -> UIBezierPath {
let offset = convert(CGPoint.zero, to: view)
return adjust(path, by: offset)
}
}