NSString sizeWithFont
вычисляется с использованием Core Text. UITextView
использует Webview (внутренне) для отображения его содержимого.
Это несоответствие приводит к всевозможным головным болям. Например, если вы хотите разбивать строки в разных местах - вы заметите списки, разделенные запятыми, и некоторые строки математических выражений будут разбиваться на разных символах между Core Text и UITextView. Это часто приводит к ошибкам построчно при измерении места для ваших строк.
А если вам нужна международная поддержка символов, вы можете забыть о высоте строки Core Text, соответствующей UITextView (независимо от того, сколько комбинаций стиля абзаца и высоты строки вы пытаетесь!).
Я обнаружил, что единственный способ надежно оценить размер для UITextView
при заданной NSString - это ... фактически построить UITextView
и прочитать его подогнанный размер (минус 8px padding ).
Вот класс 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