我正在使用下一个代码来计算字距调整(通过创建 NSString 扩展)。
此扩展使用 quicksort 的思想来快速找到使字符串适合所需宽度的字距调整。
请注意,紧缩小于-3.0会使难看的字符重叠,所以如果字符串不适合紧缩=-3,算法只会返回-3。当然你可以将 bigKern 变量设置为更小的值。
我对照 UITabBarItem(Apple 在标签栏项目标签上使用字距调整)检查了它,我的实现非常相似。
希望你喜欢。
@implementation NSString(扩展)
- (CGFloat)kernForFont:(UIFont *)font toFitWidth:(CGFloat)width
{
CGSize size = CGSizeMake(CGFLOAT_MAX, font.pointSize*2); // Size to fit.
const CGFloat threshold = 0.1;
CGFloat bigKern = -3.0, smallKern = 0.0, pivot = 0.0;
NSMutableDictionary *attrs = [NSMutableDictionary new];
attrs[NSFontAttributeName] = font;
while (true) {
attrs[NSKernAttributeName] = @(pivot);
CGRect frame = [self boundingRectWithSize:size
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attrs
context:nil];
CGFloat diff = width - frame.size.width;
if (diff > -0.5) {
// String is fitting.
if (pivot == 0.0) // Fits without kerning.
return pivot;
else if (smallKern - bigKern <= threshold)
return pivot; // Threshold is reached, return the fitting pivot.
else {
// Pivot is fitting, but threshold is not reached, set pivot as max.
bigKern = pivot;
}
}
else {
// String not fitting.
smallKern = pivot;
if (smallKern - bigKern <= threshold)
return bigKern;
}
pivot = (smallKern + bigKern) / 2.0;
}
return bigKern;
}
@end
示例用法,用于自定义 UITabBarItems:
// I have a tabBarItem of type UITabBarItem. textColor is a UIColor.
NSString *title = tabBarItem.title;
CGFloat textLabelWidth = tabBar.frame.size.width / (CGFloat)(self.tabBar.items.count) - 6.0; // 6 is padding.
UIFont *font = [UIFont systemFontOfSize:10.0];
CGFloat kern = [title kernForFont:font toFitWidth:textLabelWidth];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.alignment = NSTextAlignmentCenter;
NSDictionary *attrs = @{
NSFontAttributeName: font,
NSKernAttributeName: @(kern),
NSForegroundColorAttributeName: textColor,
NSParagraphStyleAttributeName: paragraphStyle
};
textLabel.attributedText = [[NSAttributedString alloc] initWithString:title attributes:attrs];