Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 如何获取CGPath的CGPoint_Iphone_Objective C_Ios - Fatal编程技术网

Iphone 如何获取CGPath的CGPoint

Iphone 如何获取CGPath的CGPoint,iphone,objective-c,ios,Iphone,Objective C,Ios,如何获取包含给定CGPath(CGMutablePathRef)中所有CGPoint)的数组?您可以使用该数组对路径中的每个段进行迭代,并使用该段运行自定义函数。这将为您提供路径的所有信息 但是,如果您所说的“所有CGPoint(s)”,是指每个渲染了像素的点,那么这是一个无限大的集合。虽然您当然可以使用apply函数来获取每个段,然后对于每个非移动段,使用段的控制点评估您自己的数学,以获得任意密度的点列表。aCGPath是一种不透明的数据类型,不一定存储所有使用的点。除此之外,路径实际上不能画

如何获取包含给定
CGPath
CGMutablePathRef
)中所有
CGPoint
)的数组?

您可以使用该数组对路径中的每个段进行迭代,并使用该段运行自定义函数。这将为您提供路径的所有信息


但是,如果您所说的“所有CGPoint(s)”,是指每个渲染了像素的点,那么这是一个无限大的集合。虽然您当然可以使用apply函数来获取每个段,然后对于每个非移动段,使用段的控制点评估您自己的数学,以获得任意密度的点列表。

a
CGPath
是一种不透明的数据类型,不一定存储所有使用的点。除此之外,路径实际上不能画出所有用作输入的点(例如,考虑BéZier控制点)。


从路径中获取信息的唯一两种方法是使用
CGPathGetBoundingBox
获取边界框,或者使用
CGPathApply
调用回调函数的更复杂方法,该函数将在
CGPathElement
类型时为您提供一个序列。

使用Swift 2.x(对于Swift 3.xSwift 4.xSwift 5.x请阅读以下内容……),我发现了这篇关于的精彩文章

正如她所说的,试图获得“所有的
CGPoint
(s)”,这可能是个坏主意

因此,我认为最好的方法是获取路径元素点,用于创建特定的
CGPath

//MARK: - CGPath extensions
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)
    }

    func getPathElementsPoints() -> [CGPoint] {
        var arrayPoints : [CGPoint]! = [CGPoint]()
        self.forEach { element in
            switch (element.type) {
            case CGPathElementType.MoveToPoint:
                arrayPoints.append(element.points[0])
            case .AddLineToPoint:
                arrayPoints.append(element.points[0])
            case .AddQuadCurveToPoint:
                arrayPoints.append(element.points[0])
                arrayPoints.append(element.points[1])
            case .AddCurveToPoint:
                arrayPoints.append(element.points[0])
                arrayPoints.append(element.points[1])
                arrayPoints.append(element.points[2])
            default: break
            }
        }
        return arrayPoints
    }
}
Swift 3.x和Swift 4.1(查看下面的Swift 4.2或major..) (由于重新引入了
@convention(c)
,因此有一些更正):

扩展路径{
func forEach(正文:@convention(block)(CGPathElement)->Void){
typealias Body=@约定(块)(CGPathElement)->Void
让回调:@convention(c)(UnsafeMutableRawPointer,UnsafePointer)->Void={(info,element)in
让body=unsafeBitCast(信息,收件人:body.self)
主体(element.pointee)
}
打印(MemoryLayout.size(of值:正文))
让unsafeBody=unsafeBitCast(body,to:UnsafeMutableRawPointer.self)
apply(信息:unsafeBody,函数:unsafeBitCast(回调,到:cgpathappierfunction.self))
}
func getPathElementsPoints()->[CGPoint]{
变量数组点:[CGPoint]!=[CGPoint]()
中的self.forEach{element
开关(元件类型){
案例CGPathElementType.moveToPoint:
arrayPoints.append(元素点[0])
case.addLineToPoint:
arrayPoints.append(元素点[0])
case.addQuadCurveToPoint:
arrayPoints.append(元素点[0])
arrayPoints.append(element.points[1])
case.addCurveToPoint:
arrayPoints.append(元素点[0])
arrayPoints.append(element.points[1])
arrayPoints.append(element.points[2])
默认值:中断
}
}
返回数组点
}
func getPathElementsPointsAndTypes()->([CGPoint],[CGPathElementType]){
变量数组点:[CGPoint]!=[CGPoint]()
var arrayTypes:[CGPathElementType]!=[CGPathElementType]()
中的self.forEach{element
开关(元件类型){
案例CGPathElementType.moveToPoint:
arrayPoints.append(元素点[0])
arrayTypes.append(element.type)
case.addLineToPoint:
arrayPoints.append(元素点[0])
arrayTypes.append(element.type)
case.addQuadCurveToPoint:
arrayPoints.append(元素点[0])
arrayPoints.append(element.points[1])
arrayTypes.append(element.type)
arrayTypes.append(element.type)
case.addCurveToPoint:
arrayPoints.append(元素点[0])
arrayPoints.append(element.points[1])
arrayPoints.append(element.points[2])
arrayTypes.append(element.type)
arrayTypes.append(element.type)
arrayTypes.append(element.type)
默认值:中断
}
}
返回(arrayPoints、arrayTypes)
}
}
Swift>4.1(也是Swift 5.x)和iOS 9.x及>兼容
扩展路径{
func forEach(主体:@escaping@convention(block)(CGPathElement)->Void){
typealias Body=@约定(块)(CGPathElement)->Void
让回调:@convention(c)(UnsafeMutableRawPointer,UnsafePointer)->Void={(info,element)in
让body=unsafeBitCast(信息,收件人:body.self)
主体(element.pointee)
}
//打印(MemoryLayout.size(of值:正文))
让unsafeBody=unsafeBitCast(body,to:UnsafeMutableRawPointer.self)
apply(信息:unsafeBody,函数:unsafeBitCast(回调,到:cgpathappierfunction.self))
}
func getPathElementsPoints()->[CGPoint]{
变量数组点:[CGPoint]!=[CGPoint]()
中的self.forEach{element
开关(元件类型){
案例CGPathElementType.moveToPoint:
arrayPoints.append(元素点[0])
case.addLineToPoint:
arrayPoints.append(元素点[0])
case.addQuadCurveToPoint:
arrayPoints.append(元素点[0])
arrayPoints.append(element.points[1])
case.addCurveToPoint:
arrayPoints.append(元素点[0])
arrayPoints.append(element.points[1])
arrayPoints.append(element.points[2])
默认值:中断
}
}
返回数组点
}
func getPathElementsPointsAndTypes()->([CGPoint],[CGPathElementType]){
瓦拉伊波
var bezier = UIBezierPath(ovalInRect: CGRectMake(0, 0, 400, 300))
let myOval = bezier.CGPath
let junctionPoints = myOval.getPathElementsPoints()
print("junction points are: \(junctionPoints)")
extension CGPath {

    func forEach( body: @convention(block) (CGPathElement) -> Void) {
        typealias Body = @convention(block) (CGPathElement) -> Void
        let callback: @convention(c) (UnsafeMutableRawPointer, UnsafePointer<CGPathElement>) -> Void = { (info, element) in
            let body = unsafeBitCast(info, to: Body.self)
            body(element.pointee)
        }
        print(MemoryLayout.size(ofValue: body))
        let unsafeBody = unsafeBitCast(body, to: UnsafeMutableRawPointer.self)
        self.apply(info: unsafeBody, function: unsafeBitCast(callback, to: CGPathApplierFunction.self))
    }


    func getPathElementsPoints() -> [CGPoint] {
        var arrayPoints : [CGPoint]! = [CGPoint]()
        self.forEach { element in
            switch (element.type) {
            case CGPathElementType.moveToPoint:
                arrayPoints.append(element.points[0])
            case .addLineToPoint:
                arrayPoints.append(element.points[0])
            case .addQuadCurveToPoint:
                arrayPoints.append(element.points[0])
                arrayPoints.append(element.points[1])
            case .addCurveToPoint:
                arrayPoints.append(element.points[0])
                arrayPoints.append(element.points[1])
                arrayPoints.append(element.points[2])
            default: break
            }
        }
        return arrayPoints
    }

    func getPathElementsPointsAndTypes() -> ([CGPoint],[CGPathElementType]) {
        var arrayPoints : [CGPoint]! = [CGPoint]()
        var arrayTypes : [CGPathElementType]! = [CGPathElementType]()
        self.forEach { element in
            switch (element.type) {
            case CGPathElementType.moveToPoint:
                arrayPoints.append(element.points[0])
                arrayTypes.append(element.type)
            case .addLineToPoint:
                arrayPoints.append(element.points[0])
                arrayTypes.append(element.type)
            case .addQuadCurveToPoint:
                arrayPoints.append(element.points[0])
                arrayPoints.append(element.points[1])
                arrayTypes.append(element.type)
                arrayTypes.append(element.type)
            case .addCurveToPoint:
                arrayPoints.append(element.points[0])
                arrayPoints.append(element.points[1])
                arrayPoints.append(element.points[2])
                arrayTypes.append(element.type)
                arrayTypes.append(element.type)
                arrayTypes.append(element.type)
            default: break
            }
        }
        return (arrayPoints,arrayTypes)
    }
}
extension CGPath {
    func forEach( body: @escaping @convention(block) (CGPathElement) -> Void) {
        typealias Body = @convention(block) (CGPathElement) -> Void
        let callback: @convention(c) (UnsafeMutableRawPointer, UnsafePointer<CGPathElement>) -> Void = { (info, element) in
            let body = unsafeBitCast(info, to: Body.self)
            body(element.pointee)
        }
        //print(MemoryLayout.size(ofValue: body))
        let unsafeBody = unsafeBitCast(body, to: UnsafeMutableRawPointer.self)
        self.apply(info: unsafeBody, function: unsafeBitCast(callback, to: CGPathApplierFunction.self))
    }
    func getPathElementsPoints() -> [CGPoint] {
        var arrayPoints : [CGPoint]! = [CGPoint]()
        self.forEach { element in
            switch (element.type) {
            case CGPathElementType.moveToPoint:
                arrayPoints.append(element.points[0])
            case .addLineToPoint:
                arrayPoints.append(element.points[0])
            case .addQuadCurveToPoint:
                arrayPoints.append(element.points[0])
                arrayPoints.append(element.points[1])
            case .addCurveToPoint:
                arrayPoints.append(element.points[0])
                arrayPoints.append(element.points[1])
                arrayPoints.append(element.points[2])
            default: break
            }
        }
        return arrayPoints
    }
    func getPathElementsPointsAndTypes() -> ([CGPoint],[CGPathElementType]) {
        var arrayPoints : [CGPoint]! = [CGPoint]()
        var arrayTypes : [CGPathElementType]! = [CGPathElementType]()
        self.forEach { element in
            switch (element.type) {
            case CGPathElementType.moveToPoint:
                arrayPoints.append(element.points[0])
                arrayTypes.append(element.type)
            case .addLineToPoint:
                arrayPoints.append(element.points[0])
                arrayTypes.append(element.type)
            case .addQuadCurveToPoint:
                arrayPoints.append(element.points[0])
                arrayPoints.append(element.points[1])
                arrayTypes.append(element.type)
                arrayTypes.append(element.type)
            case .addCurveToPoint:
                arrayPoints.append(element.points[0])
                arrayPoints.append(element.points[1])
                arrayPoints.append(element.points[2])
                arrayTypes.append(element.type)
                arrayTypes.append(element.type)
                arrayTypes.append(element.type)
            default: break
            }
        }
        return (arrayPoints,arrayTypes)
    }
}
/// Extension to collect CGPath points
extension CGPath {

  /// this is a computed property, it will hold the points we want to extract
  var points: [CGPoint] {

     /// this is a local transient container where we will store our CGPoints
     var arrPoints: [CGPoint] = []

     // applyWithBlock lets us examine each element of the CGPath, and decide what to do
     self.applyWithBlock { element in

        switch element.pointee.type
        {
        case .moveToPoint, .addLineToPoint:
          arrPoints.append(element.pointee.points.pointee)

        case .addQuadCurveToPoint:
          arrPoints.append(element.pointee.points.pointee)
          arrPoints.append(element.pointee.points.advanced(by: 1).pointee)

        case .addCurveToPoint:
          arrPoints.append(element.pointee.points.pointee)
          arrPoints.append(element.pointee.points.advanced(by: 1).pointee)
          arrPoints.append(element.pointee.points.advanced(by: 2).pointee)

        default:
          break
        }
     }

    // We are now done collecting our CGPoints and so we can return the result
    return arrPoints

  }
}