簡體   English   中英

NSTextField具有壓縮的字體行間距…

[英]NSTextField with condensed font line spacing…

我正在嘗試了解如何在文本字段中正確顯示帶有壓縮行距的文本。 當我設置段落樣式屬性lineHeightMultiple,maximumLineHeight和minimumLineHeight時,我可以達到壓縮線條的效果,但是副作用是文本的第一行被剪切掉了。 因此,我認為我可以使用NSBaselineOffsetAttributeName(使用負值)將文本向下移動,但這似乎沒有任何效果。 我在這里使用的線高是點大小的70%,但是修剪越緊湊,截斷就會變得越差。

1)是否有更好的方法來產生壓縮的字體行間距? 2)或如何將文本渲染向下移動,以免被剪切。

<更新>

好吧,下面的回答確實可以解決使用NSTextField的解決方案。 但這顯然對NSTextView也不起作用。 我厭倦了在NSLayoutManagerDelegate的shouldSetLineFragmentRect ...方法中重寫baselineOffset,但是它也忽略了基線調整。 有人在使用NSTextView時有任何建議嗎?

</ update>

謝謝!

這是我正在使用的測試項目https://www.dropbox.com/s/jyshqeuirujf71g/WhatThe.zip?dl=0

用裁剪的頂部文字進行渲染

編碼:

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;

好。 通過子類化NSTextFieldCell,我能夠正確地抵消文本。 可惜的是,這種方法在iOS平台上效果很好。 也許在今年夏天發布統一的Mac / iOS UI API時可以使用。 😁

這將在字符串繪制之前以及從移位的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