3

我正在使用drawRect文本显示,调用NSString. 我正在尝试使用sizeWithFont默认字体大小为 17 来自动调整字体大小(缩小)并使用循环将字体大小减小 1,如果它不适合宽度的大小。谁能帮助我如何实现这一点?现在的例子会很好,我只是将字体大小设置为 17.0

[[self.string displayName] drawAtPoint:CGPointMake(xcoord, ycoord) withFont:[UIFont boldSystemFontOfSize:17.0]];
CGSize size = [[self.patient displayName] sizeWithFont:[UIFont boldSystemFontOfSize:17.0]];
max_current_y = size.height > max_current_y ? size.height : max_current_y;
xcoord = xcoord + 3.0f + size.width;
4

7 回答 7

12

好吧,那算了。这是使用 NSString 为其返回字体的相同方法的修改版本:

    -(UIFont*)getFontForString:(NSString*)string
               toFitInRect:(CGRect)rect
                  seedFont:(UIFont*)seedFont{
    UIFont* returnFont = seedFont;
    CGSize stringSize = [string sizeWithAttributes:@{NSFontAttributeName : seedFont}];

    while(stringSize.width > rect.size.width){
        returnFont = [UIFont systemFontOfSize:returnFont.pointSize -1];
        stringSize = [string sizeWithAttributes:@{NSFontAttributeName : returnFont}];
    }

    return returnFont;
}

以下是如何调用它:

NSString* stringToDraw = @"Test 123";

    CGRect rect = CGRectMake(100., 100., 100., 200.);
    UIFont* font = [self getFontForString:stringToDraw toFitInRect:rect seedFont:[UIFont systemFontOfSize:20]];
    [stringToDraw drawInRect:rect withFont:font];

代码适用于 iOS7+

于 2013-02-11T21:01:32.273 回答
9

尝试使用 1.0 步的字体大小可能会很慢。您可以通过对两种不同尺寸进行两种测量来极大地改进算法,然后使用线性近似来猜测与正确尺寸非常接近的尺寸。

如果结果不够接近,请使用猜测的大小而不是前两个之一重复计算,直到它足够好或停止变化:

// any values will do, prefer those near expected min and max
CGFloat size1 = 12.0, size2 = 56.0; 
CGFloat width1 = measure_for_size(size1);
CGFloat width2 = measure_for_size(size2);

while (1) {
    CGFloat guessed_size = size1 + (required_width - width1) * (size2 - size1) / (width2 - width1);

    width2 = measure_for_size(guessed_size);
    if ( fabs(guessed_size-size2) < some_epsilon || !is_close_enough(width2, required_width) ) {
        size2 = guessed_size;
        continue;
    }
    // round down to integer and clamp guessed_size as appropriate for your design
    return floor(clamp(guessed_size, 6.0, 24.0));
}

is_close_enough()实施完全取决于您。鉴于文本宽度几乎与字体大小呈线性增长,您可以简单地删除它并进行 2-4 次迭代,这应该足够了。

于 2013-02-11T18:53:04.240 回答
5

我想尝试制作一个不必使用 do...while 循环反复检查字体大小的版本。相反,我假设字体点大小是线性比例,然后计算出所需框架宽度和实际框架宽度之间的大小差异,然后相应地调整字体大小。因此,我最终得到了这个功能:

+ (CGFloat)fontSizeToFitString:(NSString *)string inWidth:(float)width withFont:(UIFont *)font
{
    UILabel *label = [UILabel new];
    label.font = font;
    label.text = string;
    [label sizeToFit];

    float ratio = width / label.frame.size.width;
    return font.pointSize * ratio;
}

传入任意大小的字体,以及字符串和所需的宽度,它将返回该字体的磅值。

我还想更进一步,找出多行字符串的字体大小,这样最长的行就可以不换行了:

+ (CGFloat)fontSizeToFitLongestLineOfString:(NSString *)string inWidth:(float)width withFont:(UIFont *)font
{
    NSArray *stringLines = [string componentsSeparatedByString:@"\n"];

    UILabel *label = [UILabel new];
    label.font = font;

    float maxWidth = 0;

    for(NSString *line in stringLines)
    {
        label.text = line;
        [label sizeToFit];
        maxWidth = MAX(maxWidth, label.frame.size.width);
    }

    float ratio = width / maxWidth;
    return font.pointSize * ratio;
}

对我来说似乎工作得很好。希望它可以帮助别人。

于 2014-07-17T14:39:43.667 回答
1

原始海报没有说明他正在开发什么平台,但对于 Mavericks 上的 OSX 开发人员来说,sizeWithFont:不存在,应该使用sizeWithAttributes

NSSize newSize = [aString sizeWithAttributes:
[NSDictionary dictionaryWithObjectsAndKeys:
           [NSFont fontWithName:@"Arial Rounded MT Bold" size:53.0],NSFontAttributeName,nil
]];
于 2013-11-25T21:53:59.017 回答
0

这是一种可以返回适合矩形的字体的方法:

-(UIFont*)getFontToFitInRect:(CGRect)rect seedFont:(UIFont*)seedFont{
    UIFont* returnFont = seedFont;
    CGSize stringSize = [self sizeWithFont:returnFont];

    while(stringSize.width > rect.size.width){
        returnFont = [UIFont systemFontOfSize:returnFont.pointSize -1];
        stringSize = [self sizeWithFont:returnFont];
    }

    return returnFont;
}

您可以将此方法添加到 NSString 类别。您可以在此处找到有关如何添加类别的更多信息:http: //developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html#//apple_ref/doc/uid/TP40011210 -CH6-SW2

如果您不想创建类别,可以将此方法添加到您的实用程序类之一,并传入您希望为其返回字体的字符串。

于 2013-02-11T19:02:48.523 回答
0

这是另一种方法,受@puru020 和@jowie 答案的启发。希望它可以帮助某人

-(UIFont *) adjustedFontSizeForString:(NSString *)string forWidth:(float)originalWidth forFont:(UIFont *)font
{
    CGSize stringSize = [string sizeWithFont:font];
    if(stringSize.width <= originalWidth)
    {
        return font;
    }
    float ratio = originalWidth / stringSize.width;
    float fontSize = font.pointSize * ratio;
    return [font fontWithSize:fontSize];
}
于 2015-01-07T07:28:11.907 回答
0

我对 @puru020 的解决方案进行了一些修改,添加了对属性的支持,并进行了一些改进:

注意:该方法应该被包裹在一个 NSString 类别中

- (UIFont*)requiredFontToFitInSize:(CGSize)size seedFont:(UIFont*)seedFont attributes:(NSDictionary*)attributes{
   UIFont *returnFont = [UIFont systemFontOfSize:seedFont.pointSize +1];
   NSMutableDictionary *mutableAttributes = attributes.mutableCopy;
   CGSize stringSize;

   do {
    returnFont = [UIFont systemFontOfSize:returnFont.pointSize -1];
    [mutableAttributes setObject:returnFont forKey:NSFontAttributeName];
    stringSize = [self sizeWithAttributes:mutableAttributes];
   } while (stringSize.width > size.width);

   return returnFont;
}
于 2015-11-17T12:31:16.990 回答