-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathNSAttributedString+CXACoreTextFrameSize.m
More file actions
50 lines (43 loc) · 1.78 KB
/
Copy pathNSAttributedString+CXACoreTextFrameSize.m
File metadata and controls
50 lines (43 loc) · 1.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//
// NSAttributedString+CXACoreTextFrameSize.m
// CXAHyperlinkLabelDemo
//
// Created by Chen Xian'an on 1/7/13.
// Copyright (c) 2013 lazyapps. All rights reserved.
//
#import "NSAttributedString+CXACoreTextFrameSize.h"
#import <CoreText/CoreText.h>
@implementation NSAttributedString (CXACoreTextFrameSize)
- (CGSize)cxa_coreTextFrameSizeWithConstraints:(CGSize)size
{
if (!self.length)
return CGSizeZero;
// workaround for broken CTFramesetterCreateWithAttributedString
// http://stackoverflow.com/a/10019378/395213
NSParagraphStyle *ps = [self attribute:NSParagraphStyleAttributeName atIndex:0 effectiveRange:NULL];
id attrStr;
if (!ps ||
!ps.lineSpacing){
__block CGFloat maxLineSpacing = 0;
[self enumerateAttribute:NSFontAttributeName inRange:NSMakeRange(0, [self length]) options:0 usingBlock:^(id value, NSRange range, BOOL *stop) {
UIFont *f = value;
CGFloat lineSpacing = f.lineHeight - f.ascender + f.descender;
if (lineSpacing > maxLineSpacing)
maxLineSpacing = lineSpacing;
}];
NSMutableParagraphStyle *mps = ps ? [ps mutableCopy] : [[NSMutableParagraphStyle alloc] init];
mps.lineSpacing = maxLineSpacing;
attrStr = [self mutableCopy];
[attrStr addAttributes:@{NSParagraphStyleAttributeName : mps} range:NSMakeRange(0, [attrStr length])];
} else {
attrStr = self;
}
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attrStr);
CGSize constraints = size;
CGSize suggestSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter, CFRangeMake(0, [attrStr length]), NULL, constraints, NULL);
suggestSize.width = ceil(suggestSize.width);
suggestSize.height = ceil(suggestSize.height);
CFRelease(framesetter);
return suggestSize;
}
@end