我试图了解如何在文本字段中正确显示带有压缩行间距的文本。当我设置段落样式属性lineHeightMultiple,maximumLineHeight和minimumLineHeight时,我可以达到缩小线条的效果,但是一个副作用是文本的顶行被剪掉了。所以我认为我能够使用NSBaselineOffsetAttributeName(使用负值)向下移动文本,但这似乎没有任何效果。我在这里使用的线高是点大小的70%,但是剪切得越多,它就越精确。
1)是否有更好的方法来生成精简字体行间距? 2)或者如何向下移动文本渲染以使其不被剪裁。
<更新>
好的,我的答案确实解决了使用NSTextField时的解决方案。但这显然对NSTextView也不起作用。我厌倦了覆盖NSLayoutManagerDelegate的shouldSetLineFragmentRect ...方法中的baselineOffset,但它也忽略了基线调整。使用NSTextView时,任何人都有任何建议吗?
< /更新>
谢谢!
这是我正在使用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;
答案 0 :(得分:0)
确定。通过子类化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];
}