CGPathApply


(Jon Hull) #1

I am having the darnedest time trying to figure out how to use CGPathApply with a swift function in Swift 2.2+. I tried it before in Swift 1.2 and it wasn’t possible without bridging to ObjC, but I am fairly sure that changed with Swift 2. Every search I do just comes up with people saying it isn’t possible in Swift 1.

Does anyone know how to pull this off? (I am trying to read in a CGPath and create my own enum-based path struct for easy editing)

Thanks,
Jon


(Zachary Waldowski) #2

This seems to do it:
https://gist.github.com/zwaldowski/7e6eacc9dea0682690a820afa62e54ff

Problems are just like any context-based C API, you need to squeeze all
the important stuff into a word-size thing.

Cheers!
Zachary Waldowski
zach@waldowski.me

···

On Thu, May 12, 2016, at 09:04 PM, Jonathan Hull via swift-users wrote:

I am having the darnedest time trying to figure out how to use
CGPathApply with a swift function in Swift 2.2+. I tried it before in
Swift 1.2 and it wasn’t possible without bridging to ObjC, but I am
fairly sure that changed with Swift 2. Every search I do just comes up
with people saying it isn’t possible in Swift 1.

Does anyone know how to pull this off? (I am trying to read in a CGPath
and create my own enum-based path struct for easy editing)

Thanks,
Jon
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users


(Quinn “The Eskimo!”) #3

… and the best way to do that is to use a closure.

typealias CGPathApplierBlock = @convention(block) (CGPathElement) -> Void

func CGPathApplyBlock(path: CGPath, @noescape block: CGPathApplierBlock) {
   CGPathApply(path, unsafeBitCast(block, UnsafeMutablePointer<Void>.self), { info, element in
       let block2 = unsafeBitCast(info, CGPathApplierBlock.self)
       block2(element.memory)
   })
}

Share and Enjoy

···

On 13 May 2016, at 06:24, Zach Waldowski via swift-users <swift-users@swift.org> wrote:

Problems are just like any context-based C API, you need to squeeze all

--
Quinn "The Eskimo!" <http://www.apple.com/developer/>
Apple Developer Relations, Developer Technical Support, Core OS/Hardware


(Zachary Waldowski) #4

100% right. That solution is by far better if you wanted to work with
the CGPathElement, since that's block-representable. My solution was
assuming (perhaps wrongly) to want to represent it as a Swift type.
You're the best, as always! :slight_smile:

Cheers!
Zach

···

On Fri, May 13, 2016, at 12:57 AM, Quinn The Eskimo! via swift-users wrote:

On 13 May 2016, at 06:24, Zach Waldowski via swift-users > <swift-users@swift.org> wrote:

> Problems are just like any context-based C API, you need to squeeze all

… and the best way to do that is to use a closure.

typealias CGPathApplierBlock = @convention(block) (CGPathElement) -> Void

func CGPathApplyBlock(path: CGPath, @noescape block: CGPathApplierBlock)
{
   CGPathApply(path, unsafeBitCast(block,
   UnsafeMutablePointer<Void>.self), { info, element in
       let block2 = unsafeBitCast(info, CGPathApplierBlock.self)
       block2(element.memory)
   })
}

Share and Enjoy
--
Quinn "The Eskimo!" <http://www.apple.com/developer/>
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users