【问题标题】:NSTextField with condensed font line spacing…具有压缩字体行间距的 NSTextField……
【发布时间】:2018-01-31 13:20:27
【问题描述】:

我试图了解如何在文本字段中正确显示具有紧凑行距的文本。当我设置段落样式属性 lineHeightMultiple、maximumLineHeight 和 minimumLineHeight 时,我可以达到压缩线条的效果,但一个副作用是顶部的文本行被剪掉了。所以我认为我可以使用 NSBaselineOffsetAttributeName (使用负值)将文本向下移动,但这似乎没有任何效果。我在这里使用了点大小的 70% 的线高,但是剪裁越紧凑,越差。

1) 有没有更好的方法来产生浓缩的字体行距? 2) 或者你将如何向下移动文本渲染使其不会被剪裁。

好的,我在下面的回答确实解决了使用 NSTextField 时的解决方案。但这显然也不适用于 NSTextView。我厌倦了重写 NSLayoutManagerDelegate 的 shouldSetLineFragmentRect... 方法中的 baselineOffset,但它也忽略了基线调整。在使用 NSTextView 时,有人有什么建议吗?

谢谢!

这是我正在使用的测试项目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;

【问题讨论】:

    标签: cocoa nstextfield appkit nstextview nsparagraphstyle


    【解决方案1】:

    好的。通过继承 NSTextFieldCell 我能够正确地偏移文本。遗憾的是,这种方法在 iOS 领域运行良好。也许这会在今年夏天发布统一的 Mac/iOS UI API 时起作用。 ?

    这将在字符串绘制之前从字符串中删除所有负基线值,并在移位的矩形内绘制。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-19
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多