简体   繁体   English

NSLayoutManager / NSTextContainer忽略比例因子

[英]NSLayoutManager/NSTextContainer Ignores Scale Factor

I am attempting to measure an NSAttributedString 's height given a constant width using the following method: 我试图使用以下方法测量给定恒定宽度的NSAttributedString的高度:

-(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
}

Basically, the width is the table view's size minus the scroller and a little bit of each cell that is used to display other information. 基本上,宽度是表格视图的大小减去滚动条,以及用于显示其他信息的每个单元格的一小部分。 This method works really well as long as the text scale (via convertSliderValueToFontScale: ) is 1.0. 只要文本比例(通过convertSliderValueToFontScale:为1.0,此方法convertSliderValueToFontScale:很好地工作。 The result from usedRectForTextContainer is incorrect if I change the scale factor, however -- as if the scale factor was not being accounted for. 如果改变比例因子, usedRectForTextContainer的结果是不正确的 - 好像没有考虑比例因子。

The scale is set in setScaleFactor:forTextView: on the NSTextView as follows (scalar is the actual scale amount): 比例在setScaleFactor:forTextView:设置setScaleFactor:forTextView:在NSTextView上如下(标量是实际比例量):

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

Any ideas on how to fix this? 有想法该怎么解决这个吗?

Edit: I've got a sample project to try here: Github . 编辑:我有一个示例项目在这里尝试: Github Strangely enough, things work if the scale is < 0, and they randomly seem to work in the 4.XXX range on occasion... 奇怪的是,如果比例小于0,事情就会起作用,并且它们随机似乎在4.XXX范围内随机工作......

The answer turns out to be simple: add the NSTextView as a subview of an NSClipView with the same frame as the NSTextView . 答案结果是简单:添加NSTextView作为的子视图NSClipView具有相同的帧作为NSTextView

The final height function is as follows: 最终的高度函数如下:

-(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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM