我正在使用方法[string sizeWithFont:constrainedToSize:lineBreakMode:]
来估算我正在调整大小的textView
的高度。但是,它似乎始终返回不正确的大小。为了调试,我编写了以下代码:
self.textView.font = [UIFont systemFontOfSize:14.0]; // It was this before, anyways
NSLog(@"Real width: %lf %lf", self.textView.contentSize.width, self.textView.frame.size.width);
NSLog(@"Real height: %lf", self.textView.contentSize.height);
NSLog(@"Estimated width: %lf", kOTMessageCellTextWidth);
NSLog(@"Estimated height: %lf", ([message.message sizeWithFont:[UIFont systemFontOfSize:14.0]
constrainedToSize:CGSizeMake(kOTMessageCellTextWidth, CGFLOAT_MAX)
lineBreakMode:UILineBreakModeWordWrap].height));
但是,上面的代码显示我得到了不一致的结果:
实际宽度:223.000000 223.000000
实际高度:52.000000
预计宽度:223.000000
预计高度:36.000000
实际宽度:223.000000 223.000000
实际高度:142.000000
预计宽度:223.000000
预计身高:126.000000
实际宽度:223.000000 223.000000
实际高度:142.000000
预计宽度:223.000000
预计身高:126.000000
我在this similar question注意到(显然)textView
有一些填充限制了它的实际宽度。那里的建议是将宽度减少了sizeWithFont:
一些数字。建议的数字是11。
我的问题:有没有办法以编程方式实际检索此值,或者是否有一些我错过了指定此编号的文档?似乎这个数字应该是可用的,不应该被猜测和检查,但我找不到可靠的方法来识别它。
提前致谢。
答案 0 :(得分:6)
好的,经过一些(重新)搜索后,我来到了这里。
UITextView每边都有8px的填充。但是UILabel(和sizeWithFont方法的结果)
的行高也不一样在我的情况下,字体是Arial,大小是16pt,textview的行高比uilabel的行高高4.5个点。所以;
代码(不是确切的代码):
CGSize constraintSize = CGSizeMake(250.0 - 16.0, MAXFLOAT);
CGSize labelSize = [message.text sizeWithFont:[UIFont fontWithName:@"Arial" size:16.0] constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
CGFloat lineCount = labelSize.height / [UIFont fontWithName:@"Arial" size:16.0].lineHeight;
CGFloat additional = lineCount * 4.5; // for 16.0 pt Arial for now
return labelSize.height + additional + 16.0; // TextView fix
我仍然遇到一些问题而且不喜欢我解决它的方式。但这个问题似乎还可以。如果有人为此提供合理的解决方案,那就太好了。
答案 1 :(得分:4)
修复很简单,因为UITextView每边都有8px的填充,所以当你计算文本的真实大小时,你应该首先减去这个16px填充(双面8px),然后结果是正确的。请参阅以下代码段:
// self.descView is an UITextView
// UITEXTVIEW_TEXT_PADDING is 8.0
CGSize constrainedSize = CGSizeMake(self.descView.contentSize.width-UITEXTVIEW_TEXT_PADDING*2, MAXFLOAT);
CGSize trueSize = [self.descView.text sizeWithFont:self.descView.font
constrainedToSize:constrainedSize
lineBreakMode:UILineBreakModeWordWrap];
CGSize contentSize = self.descView.contentSize;
contentSize.height = trueSize.height;
self.descView.contentSize = contentSize;
frame = self.descView.frame;
frame.size.height = contentSize.height ;
self.descView.frame = frame;
结果应该是正确的。
答案 2 :(得分:3)
NSString sizeWithFont
。 UITextView
使用Webview(内部)呈现其内容。
这种差异会导致各种令人头疼的问题。比如选择在不同位置断行 - 你会注意到逗号分隔的列表,并且某些数学表达式字符串将在Core Text和UITextView之间的不同符号上中断。在测量弦的空间以适应时,这通常会导致一线错误。
如果您想要国际角色支持 - 那么,您可以忘记与UITextView匹配的核心文本行高(无论您尝试多少种段落样式和行高!)。
我发现唯一方法可靠地估计给定NSString的UITextView
的大小是......实际构造UITextView
并读取其拟合大小(减去8px填充)。
这是一个UIKitLineMetrics类,它就是这样做的。
它保留了两个“虚拟”文本视图。您可以使用所需的字体和布局宽度更新实例,并且可以从中读取单行和多行大小。
<强> UIKitLineMetrics.h 强>
#import <UIKit/UIKit.h>
@interface UIKitLineMetrics : NSObject
@property (nonatomic, strong) NSMutableAttributedString *attributedString;
- (CGSize) UIKitLineSizeForText:(NSString*)text;
- (CGSize) UIKitSingleLineSizeForText:(NSString*)text;
- (void) updateWithFont:(UIFont*)font andWidth:(CGFloat)width;
@end
<强> UIKitLineMetrics.m 强>
#import "UIKitLineMetrics.h"
@interface UIKitLineMetrics ()
@property (nonatomic, strong) UITextView *measuringTextView;
@property (nonatomic, strong) UITextView *measuringSingleTextView;
@end
@implementation UIKitLineMetrics
@synthesize measuringTextView;
@synthesize measuringSingleTextView;
@synthesize attributedString;
- (id) init
{
self = [super init];
if( self )
{
attributedString = [[NSMutableAttributedString alloc] init];
measuringTextView = [[UITextView alloc] initWithFrame:CGRectZero];
measuringSingleTextView = [[UITextView alloc] initWithFrame:CGRectZero];
}
return self;
}
- (CGSize) UIKitLineSizeForText:(NSString*)text
{
measuringTextView.text = [text stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
CGSize sz = [measuringTextView sizeThatFits:CGSizeMake(measuringTextView.frame.size.width, CGFLOAT_MAX)];
return CGSizeMake(sz.width - 16, sz.height - 16);
}
- (CGSize) UIKitSingleLineSizeForText:(NSString*)text
{
measuringSingleTextView.text = [text stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
CGSize sz = [measuringSingleTextView sizeThatFits:CGSizeMake(measuringSingleTextView.frame.size.width, CGFLOAT_MAX)];
return CGSizeMake(sz.width - 16, sz.height - 16);
}
- (void) updateWithFont:(UIFont*)font andWidth:(CGFloat)width
{
measuringTextView.font = font;
measuringSingleTextView.font = font;
measuringTextView.frame = CGRectMake(0, 0, width, 500);
measuringSingleTextView.frame = CGRectMake(0, 0, 50000, 500);
}
@end
答案 3 :(得分:0)
您可以尝试检查contentInset
值(UIScrollView
的属性)。
答案 4 :(得分:0)
我也在努力解决这个问题。我通常通过传递sizeWithFont方法获得的大小小于textView的实际大小。即使将textview的内容插入添加到大小,它也不起作用。返回的大小总是较小。
答案 5 :(得分:-1)
我使用以下功能没有太多问题:
+(float) calculateHeightOfTextFromWidth:(NSString*) text: (UIFont*)withFont: (float)width :(UILineBreakMode)lineBreakMode
{
[text retain];
[withFont retain];
CGSize suggestedSize = [text sizeWithFont:withFont constrainedToSize:CGSizeMake(width, FLT_MAX) lineBreakMode:lineBreakMode];
[text release];
[withFont release];
return suggestedSize.height;
}