首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用kerning动态调整文本大小以占用UILabel的全部宽度

使用kerning动态调整文本大小以占用UILabel的全部宽度
EN

Stack Overflow用户
提问于 2014-08-18 10:18:45
回答 1查看 373关注 0票数 3

我有一个布局,UILabel放置在固定宽度视图之上,下面显示为灰色矩形。

文本需要匹配固定灰色视图的宽度。

为此,我将UILabel上的UILabel属性设置为YES,将字体大小设置为非常大的字体,并将minimumScaleFactor设置为合适的小字体。这个工作很好直到…

我不得不在这段文字中加上克尔宁。我通过将@{NSKernAttributeName: @1.40}应用于属性化字符串来添加kerning,然后传递属性字符串UILabelattributedText属性。不幸的是,这似乎阻碍了自动缩放,因为这会导致文本被正确地角化,但是字符串的结尾被截断。这就好像标签缩小了文本,而没有考虑到kerning。

如何使用我选择的宽度(即灰色视图的宽度)来呈现给定的字符串和?

EN

回答 1

Stack Overflow用户

发布于 2017-10-01 22:30:40

我正在使用下一段代码来计算kerning (通过创建NSString扩展)。

这个扩展是使用快速排序思想的枢轴,以迅速找到角化,使字符串适合所需的宽度。

请注意,kerning 小于-3.0会造成难看的字符重叠,因此如果字符串与kerning = -3不匹配,则算法只返回-3。当然,您可以将bigKern变量设置为较小的值。

我在UITabBarItem's上检查了它(苹果在标签栏项目标签上使用了kerning ),我的实现非常类似。

希望你喜欢它。

@implementation NSString (分机)

代码语言:javascript
复制
- (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:

代码语言:javascript
复制
// 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];
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25360991

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档