2016-08-22 3 views
0

Я пытаюсь измерить высоту NSAttributedString «s учитывая постоянную ширину, используя следующий метод:NSLayoutManager/NSTextContainer Игнорирует Scale Factor

-(CGFloat)calculateHeightForAttributedString:(NSAttributedString*)attributedNotes { 
    CGFloat scrollerWidth = [NSScroller scrollerWidthForControlSize:NSRegularControlSize scrollerStyle:NSScrollerStyleLegacy]; 
    CGFloat width = self.tableView.frame.size.width - self.cellNotesWidthConstraint - scrollerWidth; 
    // http://www.cocoabuilder.com/archive/cocoa/54083-height-of-string-with-fixed-width-and-given-font.html 
    NSTextView *tv = [[NSTextView alloc] initWithFrame:NSMakeRect(0, 0, width - 20, 1e7)]; 
    tv.font = [NSFont userFontOfSize:32]; 
    [tv.textStorage setAttributedString:attributedNotes]; 
    [self setScaleFactor:[self convertSliderValueToFontScale:self.fontScaleSlider] forTextView:tv]; 

    [tv.layoutManager glyphRangeForTextContainer:tv.textContainer]; 
    [tv.layoutManager ensureLayoutForTextContainer:tv.textContainer]; 

    return [tv.layoutManager usedRectForTextContainer:tv.textContainer].size.height + 10.0f; // add a little bit of a buffer 
} 

В основном, ширина размер табличного представления минус скроллер и немного бит каждой ячейки, которая используется для отображения другой информации. Этот метод работает очень хорошо, пока масштаб текста (через convertSliderValueToFontScale:) равен 1,0. Результат от usedRectForTextContainer неверен, если изменить масштабный коэффициент, однако, как если бы масштабный коэффициент не учитывался.

Шкала устанавливается в setScaleFactor:forTextView: на NSTextView следующим образом (скаляр фактическая шкала сумма):

[textView scaleUnitSquareToSize:NSMakeSize(scaler, scaler)]; 

Любые идеи о том, как это исправить?

Редактировать: У меня есть образец проекта, чтобы попробовать здесь: Github. Как ни странно, все работает, если масштаб < 0, и они случайно, кажется, работают в диапазоне 4.xxx по случаю ...

+0

Как я понимаю, 'scaleUnitSquareToSize' изменяет размер точек, число точек в локальных координатах остается неизменным. – Willeke

+0

Я бы предположил, что NSLayoutManager/NSTextContainer знает ** что-то ** о 'scaleUnitSquareToSize', учитывая тот факт, что перенос текста корректируется по мере расширения текста (при условии, что ваш NSScrollView имеет горизонтальную прокрутку отключен). – Deadpikle

+0

'[tv sizeToFit]' может помочь. – Willeke

ответ

0

Ответ оказывается простым: добавить NSTextView как подвид в качестве NSClipView с тем же фреймом, что и NSTextView.

Заключительная функция высоты выглядит следующим образом:

-(CGFloat)calculateHeightForAttributedString:(NSAttributedString*)attributedNotes { 
    CGFloat width = self.textView.frame.size.width; 
    // http://www.cocoabuilder.com/archive/cocoa/54083-height-of-string-with-fixed-width-and-given-font.html 
    NSTextView *tv = [[NSTextView alloc] initWithFrame:NSMakeRect(0, 0, width, 1e7)]; 
    tv.horizontallyResizable = NO; 
    tv.font = [NSFont userFontOfSize:32]; 
    tv.alignment = NSTextAlignmentLeft; 
    [tv.textStorage setAttributedString:attributedNotes]; 
    [self setScaleFactor:self.slider.floatValue forTextView:tv]; 

    // In order for usedRectForTextContainer: to be accurate with a scale, you MUST 
    // set the NSTextView as a subview of an NSClipView! 
    NSClipView *clipView = [[NSClipView alloc] initWithFrame:NSMakeRect(0, 0, width, 1e7)]; 
    [clipView addSubview:tv]; 

    [tv.layoutManager glyphRangeForTextContainer:tv.textContainer]; 
    [tv.layoutManager ensureLayoutForTextContainer:tv.textContainer]; 
    return [tv.layoutManager usedRectForTextContainer:tv.textContainer].size.height; 
}