在不使用文本视图的情况下获取属性字符串的估计高度
getting estimated height of attributed string without using text view
这个问题偶尔会出现,但我还没有找到可靠的解决方案。
我想准确估计 NSAttributedString 的高度,而不必将文本放入不可见的文本视图中以获得真实高度。 (文本视图方法需要更多的处理时间)。但是我无法通过使用 boundingRectWithSize 获得始终如一的可靠值。对于我的目的来说,它已经足够接近 10 次的 9 次了,但这还不够好,因为它偶尔会导致视图被截断,其中一行文本不可见。
我的示例代码如下。输出为:
2016-06-27 08:54:17.106 TextHeightTest[14045:7574151] estimated1 225.000000
2016-06-27 08:54:17.108 TextHeightTest[14045:7574151] estimated2 209.000000
第一个值正确。
在.h文件中:
@interface ViewController : UIViewController {
NSMutableDictionary *attributes;
UIFont *font;
UITextView *sizingTextView;
CGFloat width;
}
.m 文件中:
- (void)viewDidLoad {
[super viewDidLoad];
sizingTextView = [[UITextView alloc] init];
font = [UIFont fontWithName:@"Helvetica" size:20];
width = 300;
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.alignment = NSTextAlignmentLeft;
paragraphStyle.lineSpacing = 7;
paragraphStyle.maximumLineHeight = 20;
paragraphStyle.minimumLineHeight = 20;
attributes = [[NSMutableDictionary alloc] init];
[attributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
[attributes setObject:font forKey:NSFontAttributeName];
NSString *text = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.";
NSAttributedString *attribStr = [[NSAttributedString alloc] initWithString:text attributes:attributes];
CGFloat estimated1 = [self estimateInTextView:attribStr];
NSLog(@"estimated1 %f", estimated1);
CGFloat estimated2 = [self estimateInSpace:text];
NSLog(@"estimated2 %f", estimated2);
}
- (CGFloat)estimateInTextView:(NSAttributedString *)text {
sizingTextView.attributedText = text;
return [sizingTextView sizeThatFits:CGSizeMake(width, CGFLOAT_MAX)].height;
}
- (CGFloat)estimateInSpace:(NSString *)text {
CGRect rect = [text boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attributes context:nil];
return CGRectGetHeight(rect);
}
感谢任何帮助。谢谢
根据文档,“要使用返回的大小来调整视图大小,您必须使用 ceil 函数将其值提高到最接近的较高整数。”您应该四舍五入(即使对于您的特定示例,这似乎不是问题所在)。
文本视图将文本放在文本容器中。默认情况下,文本容器在顶部和底部插入 8 磅。请参阅 textContainerInset
的文档。因此,文本视图将比文本本身所需的 space 高 16 点。
由于文本容器 lineFragmentPadding
的宽度,也可能存在换行差异,默认为左右 5 磅。不过我不确定。
对于测试,您实际上可以在给定大小的矩形中绘制字符串,并将其与在相同大小的文本视图中呈现的字符串进行比较。查看线条是否在不同点断开。在两者周围画一个框,看看文本插入的位置不同。
这个问题偶尔会出现,但我还没有找到可靠的解决方案。
我想准确估计 NSAttributedString 的高度,而不必将文本放入不可见的文本视图中以获得真实高度。 (文本视图方法需要更多的处理时间)。但是我无法通过使用 boundingRectWithSize 获得始终如一的可靠值。对于我的目的来说,它已经足够接近 10 次的 9 次了,但这还不够好,因为它偶尔会导致视图被截断,其中一行文本不可见。
我的示例代码如下。输出为:
2016-06-27 08:54:17.106 TextHeightTest[14045:7574151] estimated1 225.000000
2016-06-27 08:54:17.108 TextHeightTest[14045:7574151] estimated2 209.000000
第一个值正确。
在.h文件中:
@interface ViewController : UIViewController {
NSMutableDictionary *attributes;
UIFont *font;
UITextView *sizingTextView;
CGFloat width;
}
.m 文件中:
- (void)viewDidLoad {
[super viewDidLoad];
sizingTextView = [[UITextView alloc] init];
font = [UIFont fontWithName:@"Helvetica" size:20];
width = 300;
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.alignment = NSTextAlignmentLeft;
paragraphStyle.lineSpacing = 7;
paragraphStyle.maximumLineHeight = 20;
paragraphStyle.minimumLineHeight = 20;
attributes = [[NSMutableDictionary alloc] init];
[attributes setObject:paragraphStyle forKey:NSParagraphStyleAttributeName];
[attributes setObject:font forKey:NSFontAttributeName];
NSString *text = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.";
NSAttributedString *attribStr = [[NSAttributedString alloc] initWithString:text attributes:attributes];
CGFloat estimated1 = [self estimateInTextView:attribStr];
NSLog(@"estimated1 %f", estimated1);
CGFloat estimated2 = [self estimateInSpace:text];
NSLog(@"estimated2 %f", estimated2);
}
- (CGFloat)estimateInTextView:(NSAttributedString *)text {
sizingTextView.attributedText = text;
return [sizingTextView sizeThatFits:CGSizeMake(width, CGFLOAT_MAX)].height;
}
- (CGFloat)estimateInSpace:(NSString *)text {
CGRect rect = [text boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:attributes context:nil];
return CGRectGetHeight(rect);
}
感谢任何帮助。谢谢
根据文档,“要使用返回的大小来调整视图大小,您必须使用 ceil 函数将其值提高到最接近的较高整数。”您应该四舍五入(即使对于您的特定示例,这似乎不是问题所在)。
文本视图将文本放在文本容器中。默认情况下,文本容器在顶部和底部插入 8 磅。请参阅 textContainerInset
的文档。因此,文本视图将比文本本身所需的 space 高 16 点。
由于文本容器 lineFragmentPadding
的宽度,也可能存在换行差异,默认为左右 5 磅。不过我不确定。
对于测试,您实际上可以在给定大小的矩形中绘制字符串,并将其与在相同大小的文本视图中呈现的字符串进行比较。查看线条是否在不同点断开。在两者周围画一个框,看看文本插入的位置不同。