在预发布文档中,似乎没有Swift版本的CGPathApply。是否有同等的或替代的?我正在尝试获取CGPath的所有子路径,以便可以从其他起点重绘它。
在Swift 3.0中,您可以这样使用CGPath.apply:
CGPath.apply
let path: CGPath = ... // or let path: CGMutablePath path.apply(info: nil) { (_, elementPointer) in let element = elementPointer.pointee let command: String let pointCount: Int switch element.type { case .moveToPoint: command = "moveTo"; pointCount = 1 case .addLineToPoint: command = "lineTo"; pointCount = 1 case .addQuadCurveToPoint: command = "quadCurveTo"; pointCount = 2 case .addCurveToPoint: command = "curveTo"; pointCount = 3 case .closeSubpath: command = "close"; pointCount = 0 } let points = Array(UnsafeBufferPointer(start: element.points, count: pointCount)) Swift.print("\(command) \(points)") }
通过添加@convention(c),您现在可以CGPathApply直接从Swift进行调用。这是做必要魔术的包装器:
@convention(c)
CGPathApply
extension CGPath { func forEach(@noescape body: @convention(block) (CGPathElement) -> Void) { typealias Body = @convention(block) (CGPathElement) -> Void func callback(info: UnsafeMutablePointer<Void>, element: UnsafePointer<CGPathElement>) { let body = unsafeBitCast(info, Body.self) body(element.memory) } print(sizeofValue(body)) let unsafeBody = unsafeBitCast(body, UnsafeMutablePointer<Void>.self) CGPathApply(self, unsafeBody, callback) } }
(请注意,@convention(c)我的代码中没有提到,但是CGPathApply在Core Graphics模块的声明中使用了它。)
用法示例:
let path = UIBezierPath(roundedRect: CGRectMake(0, 0, 200, 100), cornerRadius: 15) path.CGPath.forEach { element in switch (element.type) { case CGPathElementType.MoveToPoint: print("move(\(element.points[0]))") case .AddLineToPoint: print("line(\(element.points[0]))") case .AddQuadCurveToPoint: print("quadCurve(\(element.points[0]), \(element.points[1]))") case .AddCurveToPoint: print("curve(\(element.points[0]), \(element.points[1]), \(element.points[2]))") case .CloseSubpath: print("close()") } }