我有一个布局,UILabel
位于固定宽度视图上方,如下图所示为灰色矩形。
文本需要与固定灰色视图的宽度相匹配。
我通过将adjustsFontSizeToFitWidth
上的UILabel
属性设置为YES
来实现此目的,将字体大小设置为非常大的值,并将minimumScaleFactor
设置为适合的小值。 此工作正常,直到......
我不得不在文字中添加字距。我通过将@{NSKernAttributeName: @1.40}
应用于属性字符串然后传递属性字符串UILabel
的{{1}}属性来添加字距调整。不幸的是,这似乎残留了自动缩放,因为这会导致文本被正确修改但字符串的末尾被截断。就好像标签将文本缩小而不考虑字距。
如何使用我选择的宽度(即灰色视图的宽度)来渲染具有字距的给定字符串?
答案 0 :(得分:0)
我正在使用下一代码来计算字距(通过创建NSString扩展名)。
此扩展程序正在使用 quicksort 的pivot概念来快速找到使字符串适合所需宽度的字距调整。
请注意,字符串小于-3.0 会使丑陋的字符重叠,因此如果字符串不适合kerning = -3,则算法只返回-3。当然,您可以将 bigKern 变量设置为较小的值。
我针对 UITabBarItem 进行了检查(Apple在标签栏项目标签上使用了字距调整),我的实现非常相似。
希望你喜欢它。
@implementation NSString(Extension)
- (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];