如何找到获得所需lineHeight或其他指标所需的UIFont pointSize?

时间:2014-01-08 16:12:58

标签: objective-c cocoa-touch uifont

您可以向UIFont实例询问其lineHeight指标:

UIFont *const font = [UIFont systemFontOfSize: 10];
CGFloat lineHeight = [font lineHeight];

如果我想要一个特定的lineHeight,(20,比方说),我该如何创建具有该尺寸的UIFont?

1 个答案:

答案 0 :(得分:1)

答案

我的有限分析令我惊讶地发现,可以使用线性插值。这是UIFont上的一个类别,它将执行所需的操作:

@interface UIFont (FontWithLineHeight)
+(UIFont*) systemFontWithLineHeight: (CGFloat) lineHeight;
@end

实施:

@implementation UIFont (FontWithLineHeight)
+(UIFont*) systemFontWithLineHeight:(CGFloat)lineHeight
{
  const CGFloat lineHeightForSize1 = [[UIFont systemFontOfSize: 1] lineHeight];
  const CGFloat pointSize = lineHeight / lineHeightForSize1;
  return [UIFont systemFontOfSize: pointSize];
}
@end

像这样使用:

UIFont *const font = [UIFont systemFontWithLineHeight: 20];
NSLog(@"%f", [font lineHeight]);

哪个输出:

2014-01-08 16:04:19.614 SpikeCollectionView[6309:60b] 20.000000

这就是要求的。

分析

似乎lineHeight的{​​{1}}与UIFont呈线性关系。换句话说,如果你将pointSize提高两倍,那么pointSize也会是两倍。如果您将lineHeight减半,则还会将pointSize减半。这意味着可以使用插值来查找将提供给定lineHeight或其他指标的pointSize

这是显示线性度的代码:

lineHeight

输出结果为:

const CGFloat lineHeight1 = [[UIFont systemFontOfSize: 1] lineHeight];
const CGFloat lineHeight10 = [[UIFont systemFontOfSize: 10] lineHeight];
const CGFloat lineHeight100 = [[UIFont systemFontOfSize: 100] lineHeight];
const CGFloat ratio1_10 = lineHeight10 / lineHeight1;
const CGFloat ratio10_100 = lineHeight100 / lineHeight10;
NSLog(@"%f", ratio1_10);
NSLog(@"%f", ratio10_100);

注意

我只在iOS 7上对系统字体进行了测试。其他字体在缩放到其pointSize时可能不会显示其指标的线性缩放。如果有人能够确认这是否得到保证,或者什么时候不起作用,那将是非常了不起的。如果您对其他2014-01-08 15:56:39.326 SpikeCollectionView[6273:60b] 9.999999 2014-01-08 15:56:39.329 SpikeCollectionView[6273:60b] 10.000001 尝试使用此功能并且无法使用,请评论或扩展此答案,或添加其他答案。

如果无法保证指标的线性缩放,则需要搜索所需的UIFont。您将需要一个“根查找”数字算法。 Illinois Algorithm适用于此。