简体   繁体   English

NSTextField具有压缩的字体行间距…

[英]NSTextField with condensed font line spacing…

I'm trying to understand how to properly display text with condensed line spacing in a text field. 我正在尝试了解如何在文本字段中正确显示带有压缩行距的文本。 When I set paragraph style properties lineHeightMultiple, maximumLineHeight, and minimumLineHeight I can achieve the effect of condensing the lines, but one side effect is that the top line of text just gets clipped off. 当我设置段落样式属性lineHeightMultiple,maximumLineHeight和minimumLineHeight时,我可以达到压缩线条的效果,但是副作用是文本的第一行被剪切掉了。 So I thought that I'd just be able to move the text down with NSBaselineOffsetAttributeName (using a negative value), but that doesn't seem to have any effect. 因此,我认为我可以使用NSBaselineOffsetAttributeName(使用负值)将文本向下移动,但这似乎没有任何效果。 I'm using a line height here of 70% of the point size, but the clipping gets far worse the more condensed it gets. 我在这里使用的线高是点大小的70%,但是修剪越紧凑,截断就会变得越差。

1) Is there a better way to produce a condensed font line spacing? 1)是否有更好的方法来产生压缩的字体行间距? 2) Or how would you move the text rendering downward so it doesn't get clipped. 2)或如何将文本渲染向下移动,以免被剪切。

<update> <更新>

Ok my answer below does address a solution when using NSTextField's. 好吧,下面的回答确实可以解决使用NSTextField的解决方案。 But this obviously doesn't work for NSTextView's too. 但这显然对NSTextView也不起作用。 I tired to override the baselineOffset in the NSLayoutManagerDelegate's shouldSetLineFragmentRect... method, but it also ignores baseline adjustments. 我厌倦了在NSLayoutManagerDelegate的shouldSetLineFragmentRect ...方法中重写baselineOffset,但是它也忽略了基线调整。 Anyone have any suggestions when working with the NSTextView? 有人在使用NSTextView时有任何建议吗?

</update> </ update>

Thanks! 谢谢!

Here's the test project I'm working with https://www.dropbox.com/s/jyshqeuirujf71g/WhatThe.zip?dl=0 这是我正在使用的测试项目https://www.dropbox.com/s/jyshqeuirujf71g/WhatThe.zip?dl=0

用裁剪的顶部文字进行渲染

Codez: 编码:

self.label.wantsLayer = YES;
self.label.backgroundColor = [NSColor whiteColor];
self.label.hidden = NO;
self.label.maximumNumberOfLines = 0;

NSMutableDictionary *result = [NSMutableDictionary dictionary];

NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];

NSFont *font = [NSFont systemFontOfSize:80.0f];

CGFloat lineHeight = font.pointSize * .7f;
CGFloat natualLineHeight = font.ascender + ABS(font.descender) + font.leading;

paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
paragraphStyle.alignment = NSTextAlignmentLeft;
paragraphStyle.lineHeightMultiple = lineHeight / natualLineHeight;
paragraphStyle.maximumLineHeight = lineHeight;
paragraphStyle.minimumLineHeight = lineHeight;
paragraphStyle.paragraphSpacing = 0.0f;
paragraphStyle.allowsDefaultTighteningForTruncation = paragraphStyle.lineBreakMode != NSLineBreakByWordWrapping && paragraphStyle.lineBreakMode != NSLineBreakByCharWrapping && paragraphStyle.lineBreakMode != NSLineBreakByClipping;

result[NSParagraphStyleAttributeName] = paragraphStyle;
result[NSKernAttributeName] = @(0.0f);
result[NSBaselineOffsetAttributeName] = @(-50.0f);

result[NSFontAttributeName] = font;

result[NSForegroundColorAttributeName] = [NSColor blackColor];

NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:@"Hello\nThere" attributes:result];
self.label.attributedStringValue = attributedString;

Ok. 好。 By subclassing NSTextFieldCell I was able to offset the text correctly. 通过子类化NSTextFieldCell,我能够正确地抵消文本。 It's a shame that this method works nicely in iOS-land. 可惜的是,这种方法在iOS平台上效果很好。 Maybe this will work when the unified Mac/iOS UI APIs are released this summer. 也许在今年夏天发布统一的Mac / iOS UI API时可以使用。 😁 😁

This will remove any negative baseline values from the string before it draws and draw inside a shifted rect. 这将在字符串绘制之前以及从移位的rect内部绘制之前从字符串中删除所有负基线值。

- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
NSRect titleRect = [self titleRectForBounds:cellFrame];
NSMutableAttributedString *string = [self.attributedStringValue mutableCopy];

__block CGFloat baselineOffset = 0.0f;

[string enumerateAttributesInRange:NSMakeRange(0, string.length) options:0 usingBlock:^(NSDictionary<NSAttributedStringKey,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {

    NSNumber *offsetValue = attrs[NSBaselineOffsetAttributeName];
    if (offsetValue != nil && offsetValue.floatValue < 0.0f) {
        baselineOffset = MIN(baselineOffset, offsetValue.floatValue);
        [string removeAttribute:NSBaselineOffsetAttributeName range:range];
    }
}];

titleRect.origin.y -= baselineOffset;

[string drawInRect:titleRect];
}

在此处输入图片说明

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

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