我想NSAttributedString
用NSParagraphStyle
属性计算 a 的高度。
我认为创建行间距较大的 UILabel 会很容易,但我无法为我的UITableViewCell
.
我试图用它来计算它,boundingRectWithSize:options:
但它根本不起作用……</p>
我想NSAttributedString
用NSParagraphStyle
属性计算 a 的高度。
我认为创建行间距较大的 UILabel 会很容易,但我无法为我的UITableViewCell
.
我试图用它来计算它,boundingRectWithSize:options:
但它根本不起作用……</p>
我使用NSLayoutManager 的usedRectForTextContainer:
TextView 堆栈与 UITableView 断开连接。我回答了一个类似的 Stack Overflow 问题并解释了如何实现它。
当来自苹果的方便方法不起作用时,这个类别在大多数情况下提供了一个很好的近似值。
@implementation NSAttributedString (PixLib)
- (CGFloat)heightForWidth:(CGFloat)width {
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectMake(0, 0, width, 99999));
CGFloat h = [self heightForPath:path];
CGPathRelease(path);
return h;
}
- (CGFloat)heightForPath:(CGPathRef)path {
CGFloat height = 0;
CTFrameRef frame = [self cfframeForPath:path];
if (frame != NULL) {
NSArray* lines = (__bridge NSArray*)CTFrameGetLines(frame);
int l = [lines count];
if (l > 1) {
CGPoint origins[l];
CTFrameGetLineOrigins(frame, CFRangeMake(0, l), origins);
CGFloat yFirst = origins[0].y;
CGFloat yLast = origins[l-1].y;
CGFloat ascent, descent, leading;
CTLineGetTypographicBounds((__bridge CTLineRef)[lines objectAtIndex:l-1], &ascent, &descent, &leading);
height = ceilf((ascent+descent+leading)*1.3) + yFirst-yLast;
} else {
if (l==1) {
CGFloat ascent, descent, leading;
CTLineGetTypographicBounds((__bridge CTLineRef)[lines objectAtIndex:0], &ascent, &descent, &leading);
height = ceilf(ascent+descent+leading)*1.3;
}
}
CFRelease(frame);
}
return height;
}
- (CTFrameRef)cfframeForPath:(CGPathRef)p {
// hack to avoid bugs width different behavior in iOS <4.3 and >4.3
CGMutablePathRef path = CGPathCreateMutable();
CGRect r = CGPathGetBoundingBox(p);
CGAffineTransform t = CGAffineTransformIdentity;
t = CGAffineTransformTranslate(t, r.origin.x, r.origin.y);
t = CGAffineTransformScale(t, 1, -1);
t = CGAffineTransformTranslate(t, r.origin.x, - ( r.origin.y + r.size.height ));
CGPathAddPath(path, &t, p);
CGPathMoveToPoint(path, NULL, 0, 0);
CGPathCloseSubpath(path);
// hack end
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)self);
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), path, NULL);
CFRelease(framesetter);
CGPathRelease(path);
return frame;
}
@end