在
pre-release documentation,似乎没有Swift版本的CGPathApply.有等同还是替代?我试图获取CGPath的所有子路径,以便我可以从不同的起始点重新绘制.
Swift 3.0
在Swift 3.0中,您可以使用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)")
}
Swift 2.2
通过添加@convention(c),您现在可以直接从Swift调用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),而是在Core Graphics模块的CGPathApply声明中使用.)
使用示例
let path = UIBezierPath(roundedRect: CGRectMake(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()")
}
}