4
votes

I'm trying to convert the following Objective-C code (source) from this

-(CGRect) dimensionsForAttributedString: (NSAttributedString *) asp {

    CGFloat ascent = 0, descent = 0, width = 0;
    CTLineRef line = CTLineCreateWithAttributedString( (CFAttributedStringRef) asp);

    width = CTLineGetTypographicBounds( line, &ascent, &descent, NULL );

    // ...
}

into Swift:

func dimensionsForAttributedString(asp: NSAttributedString) -> CGRect {

    let ascent: CGFloat = 0
    let descent: CGFloat = 0
    var width: CGFloat = 0
    let line: CTLineRef = CTLineCreateWithAttributedString(asp)

    width = CTLineGetTypographicBounds(line, &ascent, &descent, nil)

    // ...
}

But I am getting the error with &ascent in this line:

width = CTLineGetTypographicBounds(line, &ascent, &descent, nil)

'&' used with non-inout argument of type 'UnsafeMutablePointer'

Xcode suggests that I fix it by deleting &. When I do that, though, I get the error

Cannot convert value of type 'CGFloat' to expected argument type 'UnsafeMutablePointer'

The Interacting with C APIs documentation uses the & syntax, so I don't see what the problem is. How do I fix this error?

1
The CTLineGetTypographicBounds function expects an UnsafeMutablePointer<CGFloat>, so for example with withUnsafeMutablePointer you should create an UnsafeMutablePointer<CGFloat>, and use that as an input parameter. - Dániel Nagy
My problem was that I hadn't declared them as variables with the var keyword. - Suragch

1 Answers

7
votes

ascent and descent must be variables in order to be passed as in-out arguments with &:

var ascent: CGFloat = 0
var descent: CGFloat = 0
let line: CTLineRef = CTLineCreateWithAttributedString(asp)
let width = CGFloat(CTLineGetTypographicBounds(line, &ascent, &descent, nil))

On return from CTLineGetTypographicBounds(), these variables will be set to the ascent and descent of the line. Note also that this function returns a Double, so you'll want to convert that to CGFloat.