NSParagraphStyle行间距被忽略

时间:2012-09-24 09:46:17

标签: objective-c uitextview ios6 nsattributedstring

失败的简单测试:使用一个子视图(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}];
}

行间距与属性不存在时相同。有没有什么能成功地运作?为了表明它不会改变,我加入了荒谬的数字......

6 个答案:

答案 0 :(得分:24)

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

问题来自于字体CSS简写中容易遗漏的特性。如果您使用字体速记指定像素大小,则此设置字体大小以及行高。由于NSHTMLWriter将字体放在行高后,这会导致行高被字体大小抵消。

请参阅此处了解我的雷达,其中包括对错误的完整分析:http://www.cocoanetics.com/2012/12/radar-uitextview-ignores-minimummaximum-line-height-in-attributed-string/

我建议您提交错误报告并提及我的雷达#12863734。

答案 1 :(得分:23)

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

关于您的属性

lineSpacing从行的底部到上面行的底部进行计算,该空间被约束为minimumLineHeightmiximumLineHeight之间的值。我想说的是,您的属性中的某些值可能是取消覆盖其他值。

此外,如果您只需要调整行之间的间距,则可能不需要使用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];

附加说明

似乎有日语/中文的情况,也许在同一行中混有字母字符的其他字符。它将使该行具有更大的前导来解决您需要设置最小和最大行高度的方法。 渲染没有属性的示例时,您可以看到问题。

答案 2 :(得分:8)

设置maximumLineHeight似乎为我解决了这个问题;

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

答案 3 :(得分:5)

对于此特定字符串,您需要设置paragraphSpacing。什么是lineSpacing,我相信它在iOS上尚未得到支持。

答案 4 :(得分:0)

正如nacho4d所说,在 iOS 6 中你需要使用 minimumLineHeight maximumLineHeight 并直接在 UITextView中设置字体,而不是 NSAttributedString ,因为在这种情况下将覆盖行高。

请注意,当您在 UITextView 中设置字体时, UITextView "可编辑" 属性应设置为,在其他情况下归因文字不会受到影响。

这些问题仅出现在 iOS 6 中。在 iOS 7 以上,一切正常;

答案 5 :(得分:0)

就我而言,段落样式都没有起作用。修复是在标签上对标签进行任何帧调整后在标签上设置属性文本。 :)