段落样式行间距被忽略。

25

一个简单的测试失败了:创建一个只有一个子视图(UITextView)的新项目,并放入以下内容:

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    paragraphStyle.lineHeightMultiple = 50.f;
    paragraphStyle.lineSpacing = 100.f;
    paragraphStyle.minimumLineHeight = 200.f;
    paragraphStyle.maximumLineHeight = 500.f;

    UIFont *font = [UIFont fontWithName:@"AmericanTypewriter" size:24.f];

    self.textView.attributedText = [[NSAttributedString alloc] initWithString:
    @"This is a test.\n Will I pass?" attributes:
    @{NSParagraphStyleAttributeName : paragraphStyle, NSFontAttributeName : font}];
}

行距与未使用属性时相同。有人成功地让它工作了吗?我放了一些荒谬的数字,只是为了表明它不会改变...


我也遇到了同样的问题,你找到解决方案了吗? - Snowman
@mohabitar 看起来解决方案是等待苹果修复它。另一种选择是使用DTCoreText并实现自己的选择。大部分选择代码都可以在苹果的一个示例中找到,名为SimpleTextInput(默认情况下已禁用,但确实存在)。 - borrrden
6个回答

24

这是NSHTMLWriter中的一个bug,它是UITextView用于将attributedText转换为HTML时使用的私有类。在内部,它通过UIWebDocumentView显示此HTML。在我的文章中阅读更多关于UITextView内部工作原理的内容:http://www.cocoanetics.com/2012/12/uitextview-caught-with-trousers-down/

问题来自于字体CSS缩写中容易忽略的特殊性。如果您在字体缩写中指定像素大小,则会设置font-size和line-height两者。由于NSHTMLWriter在line-height后面放置字体,这会导致line-height被字体大小抵消。

请参见此处的Radar,其中包括该错误的完整分析:http://www.cocoanetics.com/2012/12/radar-uitextview-ignores-minimummaximum-line-height-in-attributed-string/

我建议您也提交错误报告,并提到我的Radar号码#12863734。


我很想这么做,但实际上我从来没有成功登录到错误报告网站...我发了电子邮件进行投诉,但从未得到回复 :-S。不过这很有趣! - borrrden
你应该打电话给DTS,他们可以在那里帮助你。电话号码根据你所在的国家在网站上提供。 - Cocoanetics
1
如果苹果公司有回应,请考虑发布后续内容。谢谢! - jaredsinclair
@Cocoanetics 在iOS 7中,我这里遇到了一个类似的、可能相关的问题: http://stackoverflow.com/questions/19232006/uilabel-applying-line-break-mode-to-only-a-portion-of-the-text - Aaron Brager

23

我不知道这是否足够满足您的需求,但我可以通过设置最小和最大行高度来调整行间距。此外,为了使用字体,我将其放入文本视图的 font 属性中,而不是将其作为 NSFontAttributeName 的值传递给属性字典。(也许这部分文档不是特别好?)

关于您的属性

lineSpacing 是从底部行到上一行的底部计算出的空间,并且该空间受限于 minimumLineHeightmaximumLineHeight 之间的值。我的意思是,也许您属性中的某些值会相互取消覆盖对方。

此外,如果您只需要调整行间距,请勿使用 paragraphStyle.lineHeightMultiple :)

代码

这对我有用:

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.minimumLineHeight = 35.f;
paragraphStyle.maximumLineHeight = 35.f;

UIFont *font = [UIFont fontWithName:@"AmericanTypewriter" size:18.f];
NSString *string = @"This is a test.\nWill I pass?\n日本語のもじもあるEnglish\nEnglish y Español";
NSDictionary *attributtes = @{
    NSParagraphStyleAttributeName : paragraphStyle,
};
self.textView.font = font;
self.textView.attributedText = [[NSAttributedString alloc] initWithString:string
                                 attributes:attributtes];

额外说明

似乎存在一些情况,即日语/中文和其他字母字符混合在同一行中。这将使该行具有更大的 领先空间。为解决此问题,您需要像我所做的那样设置最小和最大行高度。当没有属性渲染我的示例时,您可以看到问题。


这可能已经足够了。我回到办公室时会进一步研究它。 - borrrden
我觉得我应该注释一下,这样做行不通,因为我会在同一个标签中混合使用不同的字体(斜体、常规等)。:-S - borrrden
只要您使用相同的字体大小,这种方法就应该有效。斜体和常规字将产生相同的行高。 - nacho4d
2
当我通过NSFontAttributeName设置字体时,行距再次被忽略...这是个大问题(因为没有其他方法在同一标签中混合样式)。https://dev59.com/vGrXa4cB1Zd3GeqPBKFO?rq=1 - borrrden
@borrrden - 你最终找到解决方案了吗?我很好奇。 - Ser Pounce

9

我发现设置最大行高可以解决这个问题;

CGFloat fontSize = 22.f;
titleLabel.font = [UIFont boldSystemFontOfSize:fontSize];
NSMutableParagraphStyle *paragraphStyle = [[[NSMutableParagraphStyle  alloc] init] autorelease];
paragraphStyle.maximumLineHeight = fontSize/2;
titleLabel.attributedText = [[[NSAttributedString alloc]
                              initWithString:@"This is a test.\nWill I pass?"
                              attributes: @{ NSParagraphStyleAttributeName : paragraphStyle,
                                             NSFontAttributeName : titleLabel.font}]
                             autorelease];

overlapping lines


5

对于这个特定的字符串,您需要设置paragraphSpacing而不是lineSpacing。至于lineSpacing,我相信它在iOS上尚未得到支持。


关于段落间距的技巧很不错 +1。但是,我想停止使用UIWebView……所以在UITextView可以使用CSS行高之前,我无法这样做...... - borrrden

0
在我的情况下,段落样式都没有起作用。解决方法是在对标签进行任何框架调整之后,在标签上设置属性文本。 :)

0

正如nacho4d所回答的,在中,您需要使用minimumLineHeightmaximumLineHeight,并直接在UITextView中设置字体,而不是在NSAttributedString中设置,因为在这种情况下,行高将被覆盖。

请注意,当您在UITextView中设置字体时,UITextView"editable"属性应设置为YES,否则attributed text将不受影响。

这些问题仅存在于中。在及以上版本中,一切都很好;


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接