What you need is CTFramesetterSuggestFrameSizeWithConstraints()
, you can use it like so:
CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)(attributedString)); /*Create your framesetter based in you NSAttrinbutedString*/
CGFloat widthConstraint = 500; // Your width constraint, using 500 as an example
CGSize suggestedSize = CTFramesetterSuggestFrameSizeWithConstraints(
framesetter, /* Framesetter */
CFRangeMake(0, text.length), /* String range (entire string) */
NULL, /* Frame attributes */
CGSizeMake(widthConstraint, CGFLOAT_MAX), /* Constraints (CGFLOAT_MAX indicates unconstrained) */
NULL /* Gives the range of string that fits into the constraints, doesn't matter in your situation */
);
CGFloat suggestedHeight = suggestedSize.height;
EDIT
//IMPORTANT: Release the framesetter, even with ARC enabled!
CFRelease(frameSetter);
As ARC releases only Objective-C objects, and CoreText deals with C, very likely you can have a memory leak here. If your NSAttributedString
is small and you do it once, you shouldn't have any bad consequences. But in a case you have a loop to calculate, let's say, 50 heights of big/complex NSAttributedString
s, and you don't release the CTFramesetterRef
, you can have serious memory leaks. Check the tutorial linked for more information on memory leaks and debugging with instruments.
So the solution for this problem is to add CFRelease(frameSetter);
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…