我有一个布局,其中 UILabel
放置在固定宽度的 View 上方,如下图所示为灰色矩形。
文本需要匹配固定灰色 View 的宽度。
我通过将 UILabel
上的 adjustsFontSizeToFitWidth
属性设置为 YES
,将字体大小设置为非常大,并将minimumScaleFactor
为合适的小值。 在……之前一切正常
我不得不为所述文本添加字距调整。我通过将 @{NSKernAttributeName: @1.40}
应用于属性字符串来添加字距调整,然后传递属性字符串 UILabel
的 attributedText
属性。不幸的是,这似乎阻碍了自动缩放,因为这会导致文本被正确调整,但字符串的末尾被截断。就好像标签在不考虑字距调整的情况下缩小了文本。
如何让给定的字符串使用字距调整以我选择的宽度(即灰色 View 的宽度)呈现?
最佳答案
我正在使用下一个代码来计算字距调整(通过创建 NSString 扩展)。
此扩展使用 quicksort pivot 的想法来快速找到使字符串适合所需宽度的字距调整。
请注意,字距调整 小于 -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];
关于cocoa-touch - 使用字距调整动态调整文本大小以占据 UILabel 的整个宽度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25360991/