2016-06-27 8 views
2

Этот вопрос появляется иногда, но мне еще предстоит найти надежное решение.получение расчетной высоты атрибутивной строки без использования текстового вида

Я хочу точно оценить высоту NSAttributedString, не перебирая текст в невидимое текстовое представление, чтобы получить истинную высоту. (В режиме просмотра текста требуется больше времени обработки). Но я не могу получить неизменно надежные значения из использования boundingRectWithSize. Это достаточно близко для моих целей 9 раз из 10, но это недостаточно хорошо, потому что иногда это приводит к усеченному виду, причем одна строка текста не видна.

Мой пример кода ниже. Выходной сигнал:

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); 

} 

Я признателен за любую помощь. Благодарю.

ответ

2

Текстовый вид помещает текст в текстовый контейнер. По умолчанию текстовый контейнер вставлен на 8 точек сверху и снизу. См. Документы для textContainerInset. Таким образом, текстовое представление будет на 16 пунктов выше, чем пространство, требуемое самим текстом.

В текстовом контейнере могут быть также разности строк, основанные на ширине, из-за текстового контейнера lineFragmentPadding, который по умолчанию равен 5 баллам слева и справа. Хотя я не уверен в этом.

Для теста вы можете нарисовать строку в прямоугольнике заданного размера и сравнить ее с строкой, отображаемой в текстовом виде того же размера. Посмотрите, не сломаны ли строки в разных точках. Нарисуйте рамку вокруг обоих и посмотрите, где текст вставляется по-разному.

+0

Спасибо Кен. Я слышал о contentInset, но до сих пор не слышал о textContainerInset. Установка textContainerInset UITextView для UIEdgeInsetsZero заставляет эти два номера выходить одинаково. Эта проблема давно искала меня. Очень признателен! (Это еще не даст мне награду, но я при первой же возможности). –

0

В соответствии с документацией, «чтобы использовать отображаемый размер для просмотра размера, вы должны использовать поднять его значение до ближайшего более высокого целого с помощью функции ceil». Вы должны округлять (даже если ваш конкретный пример это doesn Кажется, это проблема).

 Смежные вопросы

  • Нет связанных вопросов^_^