在Swift中是否等效于CGPathApply?

发布于 2021-01-31 23:45:54

预发布文档中,似乎没有Swift版本的CGPathApply。是否有同等的或替代的?我正在尝试获取CGPath的所有子路径,以便可以从其他起点重绘它。

关注者
0
被浏览
78
1 个回答
  • 面试哥
    面试哥 2021-01-31
    为面试而生,有面试问题,就找面试哥。

    斯威夫特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)")
    }
    

    斯威夫特2.2

    通过添加@convention(c),您现在可以CGPathApply直接从Swift进行调用。这是做必要魔术的包装器:

    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()")
        }
    }
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看