In iOS 17, when I try to use CTFramesetterSuggestFrameSizeWithConstraints to obtain the size of a text, if the system-provided bold font is used, the resulting rectangular area may not be sufficient to accommodate the text.
The provided example code is not allowing me to display the complete text within the CTFrame.
code:
NSString *testString = @"《测试》";
CFStringRef cfTestString = CFStringCreateWithCString(kCFAllocatorDefault, [testString cStringUsingEncoding:NSUTF8StringEncoding], kCFStringEncodingUTF8);
UIFont *uiFont = [UIFont boldSystemFontOfSize:50.0];
UIFontDescriptor *fontDescriptor = uiFont.fontDescriptor;
CTFontDescriptorRef ctFontDescriptor = (__bridge CTFontDescriptorRef)fontDescriptor;
CTFontRef ct_font = CTFontCreateWithFontDescriptor(ctFontDescriptor, uiFont.pointSize, NULL);
CGFloat color_components[4] = {1.0, 1.0, 1.0, 1.0};
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGColorRef cgColor = CGColorCreate(colorSpace, color_components);
CTParagraphStyleSetting styleSetting;
styleSetting.spec = kCTParagraphStyleSpecifierAlignment;
CTTextAlignment ctAlignment = kCTTextAlignmentCenter;
styleSetting.value = &ctAlignment;
styleSetting.valueSize = sizeof(kCTTextAlignmentCenter);
CTParagraphStyleRef ctParagraphStyle = CTParagraphStyleCreate(&styleSetting, 1);
const void* keys[] = {kCTFontAttributeName, kCTForegroundColorAttributeName,
kCTParagraphStyleAttributeName};
const void* values[] = {ct_font, cgColor, ctParagraphStyle};
CFDictionaryRef attr = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 3,
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFAttributedStringRef cfAttributedString = CFAttributedStringCreate(kCFAllocatorDefault, cfTestString, attr);
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(cfAttributedString);
CGSize constraints = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX);
CGSize stringSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, 0), NULL, constraints, NULL);
float width = ceil(stringSize.width);
float height = ceil(stringSize.height);
CGPathRef path = CGPathCreateWithRect(CGRectMake(0.0, 0.0, width, height), NULL);
CTFrameRef cfFrame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
CFRange stringRange = CTFrameGetStringRange(cfFrame);
CFRange visibleStringRange = CTFrameGetVisibleStringRange(cfFrame);
NSLog(@"stringRange.location: %@ stringRange.length: %@", @(stringRange.location), @(stringRange.length));
NSLog(@"visibleStringRange.location: %@ visibleStringRange.length: %@", @(visibleStringRange.location), @(visibleStringRange.length));
log:
stringRange.location: 0 stringRange.length: 4
visibleStringRange.location: 0 visibleStringRange.length: 2