8

I'm trying to create a CGPath in Swift. I'm using CGPathCreateWithRect(rect, transformPointer).

How can I get an UnsafePointer<CGAffineTransform> from a CGAffineTransform? I've tried this:

    let transform : CGAffineTransform = CGAffineTransformIdentity
    let transformPointer : UnsafePointer<CGAffineTransform> = UnsafePointer(transform)

I've also tried this:

    let transform : CGAffineTransform = CGAffineTransformIdentity
    let transformPointer : UnsafePointer<CGAffineTransform> = &transform 

but Swift complains about a '&' with non-inout argument of type.... I've also tried passing &transform directly into CGPathCreateWithRect but that stops with same error.

When I pass in transform directly, Swift "Cannot convert value of type 'CGAffineTransform' to expected argument type 'UnsafePointer'".

What's going on, and how can make this work with Swift 2.1?

Moshe
  • 57,511
  • 78
  • 272
  • 425

2 Answers2

18

I've also tried passing &transform directly into CGPathCreateWithRect ...

You were almost there. transform needs to be a variable in order to pass it as an inout argument with &:

var transform = CGAffineTransformIdentity
let path = CGPathCreateWithRect(CGRect(...), &transform)

For more information, see "Interacting with C APIs" in the "Using Swift with Cocoa and Objective-C" documentation.


In Swift 3 this would be

var transform = CGAffineTransform.identity
let path = CGPath(rect: rect, transform: &transform)

or, for the identity transform, just

let path = CGPath(rect: rect, transform: nil)
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • In the latest Swift/Xcode this `var transform = CGAffineTransformIdentity ` generates this error: CGAffineTransformIdentity is unavailable in Swift – Confused Oct 27 '16 at 04:29
  • The second one, with nil, is food to my eyes, a rainbow in my ears and music on my tongue! – Confused Oct 27 '16 at 08:49
  • Wow, thanks so much! Syntax in Swift 5 for this is nice, btw: `path.copy(using: &transform)` - very intuitive. – Erik van der Neut Mar 07 '21 at 06:55
3

@Martin R provides the best answer, but as an alternative, I like to use my unsafe mutable pointers this way, in case you need to alter the actual pointer in the future

let path = withUnsafeMutablePointer(&transform)
{
  CGPathCreateWithRect(CGRect(...), UnsafeMutablePointer($0))
}
Knight0fDragon
  • 16,609
  • 2
  • 23
  • 44
  • 1
    You don't need a *mutable* pointer and you don't need the pointer cast, so it can be shortened to `withUnsafePointer(&transform) { CGPathCreateWithRect(CGRect(), $0) }`. – I am fairly sure that CGPathCreateWithRect() *copies* the data and does not keep the pointer. Otherwise it would be unusable in C where you can pass the address of a (local) array to that function. – Martin R Dec 17 '15 at 20:29
  • That is true, I am not 100% familiar with CGPathCreateWithRect, I was just going off of memory on how I deal with the unsafe pointers in various situations – Knight0fDragon Dec 17 '15 at 20:33
  • 1
    Why is this the answer? I would prefer to use Martin R way first, he should get full credit for the answer, I was just pointing out a different way for unsafe mutable pointers in case people come across that problem – Knight0fDragon Dec 18 '15 at 18:26