使用Core Text的多语言布局中的行间距

时间:2011-06-16 05:54:02

标签: ios core-text

属性字符串只有一个属性 - 17点Helvetica NeueUI字体 - 覆盖整个字符串。 1~3行纯英语,4~6行是英汉混合,7~8行纯粹是中文。

然后使用CTFramesetter进行布局,并使用CTFrameDraw绘制结果帧。

// UIView subclass
- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor whiteColor];
        CTFontRef font = CTFontCreateWithName(CFSTR("Helvetica NeueUI"), 17.f, NULL);
        _text = [[NSAttributedString alloc] initWithString:string attributes:
                 [NSDictionary dictionaryWithObject:(id)font forKey:(id)kCTFontAttributeName]];
        CFRelease(font);
        _framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)_text);
        CGMutablePathRef path = CGPathCreateMutable();
        CGPathAddRect(path, NULL, self.bounds);
        _frame = CTFramesetterCreateFrame(_framesetter, CFRangeMake(0, 0), path, NULL);
        CGPathRelease(path);
    }
    return self;
}

- (void)drawRect:(CGRect)rect
{
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    // Flip the coordinate system.
    CGContextTranslateCTM(context, 0.f, self.bounds.size.height);
    CGContextScaleCTM(context, 1.f, -1.f);

    CGContextSetTextMatrix(context, CGAffineTransformIdentity);

    CTFrameDraw(_frame, context);
    CGContextRestoreGState(context);
}

问题在于第7行和第8行(纯中文行)之间的空间比其他行空间要小得多。

相比之下,我在它下面放了UILabel,字体和文字相同。忽略单个字符的渲染差异,可以看到UILabel中的行间距是统一的,包括两个中文行之间的最后一行。

Screenshot

注意:上面的结果是在真实设备上获得的。如果在模拟器上运行相同的代码,Core Text视图的结果会有很大差异 - 包含中文的行之间的空间比其他行大得多。

  1. 为什么中国线之间的空间更小(更大)?
  2. 如何使用Core Text设置具有统一线高的多语言文本?
  3. PS:这是您可以尝试的sample project

3 个答案:

答案 0 :(得分:3)

与欧洲语言中每个字母之间的空格类似,中文书写在字符之间使用了一个狭窄的空间,但除了在极少数情况下,它没有观察到相当于单词之间更宽的空间。 (在这方面,它可能有点类似于一种脚本连续性。) 使用空间时,它也是全宽的。其用法的一个实例是作为敬意标记。台湾的一个现代例子是蒋介石作为先总蒋公(前总统蒋介石),其中前面的空间是蒋公的荣誉标记。这种用法在非常正式的信件或其他旧式文件中仍然是最新的。 当汉语以音译形式书写时(如汉语拼音),空格用于辅助阅读。出处:http://en.wikipedia.org/wiki/Chinese_punctuation

所以它因为在中文中使用的空间与英语有点不同。

答案 1 :(得分:1)

我终于得到了Apple工程师的正式答复:

  

CTLine指标基于{上升,下降,每个的最大值   领导};这没有改变,也没有改变。客户可以覆盖   使用段落样式说明符或iOS 7文本样式的行指标,   例如[UIFont preferredFontForTextStyle:UIFontTextStyleBody]。

答案 2 :(得分:1)

空格的原因取决于字符,因为在查询文本的部分内容时可以找到它,但这并没有说明为什么标签只是忽略了这个问题。

然而,空间实际上是由FrameSetter引入的,为了实现均匀空间,您可以使用FrameSetter来获取换行符并使用TypeSetter(CTTypesetterCreateWithAttributedString)来生成线并将它们指向所需的线距,如显示在Manual Line Break from Apple中。这也适用于您的给定样本,正如我简要检查过的那样。

无论如何,我只能同意标签的行为有些奇怪,但不是很糟糕,因为它看起来更好。