计算字体大小以适合框架 - 核心文本 - NSAttributedString - iOS

Guy*_*ood 20 fonts objective-c nsattributedstring core-text ios

我有一些文本,我通过NSAttributedString(下面的代码)绘制到一个固定的框架.目前我正在努力将文本大小编码为16.我的问题是,有没有办法计算给定帧文本的最佳拟合大小?

- (void)drawText:(CGContextRef)contextP startX:(float)x startY:(float)
y withText:(NSString *)standString
{
    CGContextTranslateCTM(contextP, 0, (bottom-top)*2);
    CGContextScaleCTM(contextP, 1.0, -1.0);

    CGRect frameText = CGRectMake(1, 0, (right-left)*2, (bottom-top)*2);

    NSMutableAttributedString * attrString = [[NSMutableAttributedString alloc] initWithString:standString];
    [attrString addAttribute:NSFontAttributeName
                      value:[UIFont fontWithName:@"Helvetica-Bold" size:16.0]
                      range:NSMakeRange(0, attrString.length)];

    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)(attrString));
    struct CGPath * p = CGPathCreateMutable();
    CGPathAddRect(p, NULL, frameText);
    CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0,0), p, NULL);

    CTFrameDraw(frame, contextP);
}
Run Code Online (Sandbox Code Playgroud)

use*_*402 23

这是一段简单的代码,它将找出适合框架范围内的最大字体大小:

UILabel *label = [[UILabel alloc] initWithFrame:frame];
label.text = @"Some text";
float largestFontSize = 12;
while ([label.text sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize:largestFontSize]}].width > modifierFrame.size.width)
{
     largestFontSize--;
}
label.font = [UIFont systemFontOfSize:largestFontSize];
Run Code Online (Sandbox Code Playgroud)

  • 效果很好!除了一行文字.我想知道是否有办法做多行 (2认同)

Fog*_*ter 9

我能看到这种可能性的唯一方法是让系统运行大小计算,然后调整大小并重复,直到找到合适的大小.

即设置一个在某些尺寸之间的二等分算法.

即运行它的大小10.太小.尺寸20.太小.大小30.太大了.大小25.太小.大小27.恰到好处,使用大小27.

你甚至可以从数百人开始.

大小100.太大了.大小50.等...


Clo*_*ddy 6

目前接受的答案是谈论算法,但iOS提供了NSString对象的计算.我会用sizeWithAttributes:这个NSString课.

sizeWithAttributes:

返回使用给定属性绘制时接收器占用的边界框大小.

    - (CGSize)sizeWithAttributes:(NSDictionary *)attributes
Run Code Online (Sandbox Code Playgroud)

来源:Apple Docs - NSString UIKit Additions Reference

编辑错误解释了这个问题,所以这个答案是不合适的.


Hol*_*ick 6

一个小技巧有助于sizeWithAttributes:在不需要迭代正确结果的情况下使用:

NSSize sampleSize = [wordString sizeWithAttributes:
    @{ NSFontAttributeName: [NSFont fontWithName:fontName size:fontSize] }];
CGFloat ratio = rect.size.width / sampleSize.width;
fontSize *= ratio;
Run Code Online (Sandbox Code Playgroud)

确保fontSize样本足够大以获得良好的结果。


sab*_*and 5

更简单/更快(但当然是近似)的方法是:

class func calculateOptimalFontSize(textLength:CGFloat, boundingBox:CGRect) -> CGFloat
    {
        let area:CGFloat = boundingBox.width * boundingBox.height
        return sqrt(area / textLength)
    }
Run Code Online (Sandbox Code Playgroud)

我们假设每个字符是 N x N 像素,所以我们只计算 N x N 进入边界框的次数。