尽可能将圆圈中的文字放入

时间:2015-04-25 15:10:09

标签: ios objective-c

这是一个非常基本的问题,但我找不到合适的解决方案。我有几个圆圈,里面有文字,就像你在图片中看到的那样。文本动态加载,大小从一个单词到五个单词或更多。目标是将文本尽可能大地放入圆圈中。可以出现新的行,但每个单词应该保持在一起。示例图像有点好,但我希望文本更大,因为文本和圆圈之间仍然有一些自由空间。圆圈是80x80。我试过的所有解决方案都严重裁剪文字或文字太小。

我如何创建标签:

UILabel *buttonlabel = [[UILabel alloc] initWithFrame:CGRectMake(12,7,57,64)];

    [buttonlabel setText: @"Recipes"];
    buttonlabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:18.0f];
    buttonlabel.textColor = [UIColor whiteColor];
    buttonlabel.textAlignment = NSTextAlignmentCenter;
    buttonlabel.lineBreakMode = NSLineBreakByWordWrapping;
    buttonlabel.numberOfLines = 3;
   [button addSubview:buttonlabel];
   [buttonlabel release];

enter image description here

修改: 所以我尝试了Rufel的解决方案。我认为缩小的作品,但我的话被撕裂了。即使我有buttonlabel.lineBreakMode = NSLineBreakByWordWrapping;

看起来像这样:

enter image description here

这是我的代码。我还实现了答案中提到的其他方法。

//Create the button labels
    UILabel *buttonlabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 60, 60)];


    [buttonlabel setText: @"text";
    buttonlabel.textColor = [UIColor whiteColor];
    buttonlabel.textAlignment = NSTextAlignmentCenter;
    buttonlabel.lineBreakMode = NSLineBreakByWordWrapping;

    buttonlabel.numberOfLines = 0;

    CGFloat fontSize = 20; // The max font size you want to use
    CGFloat labelHeightWithFont = 0;
    UIFont *labelFont = nil;

    do {
        // Trying the current font size if it fits
        labelFont = [UIFont systemFontOfSize:fontSize--];
        CGRect boundingRect = [self boundingRectForString:subcatbuttontitlesarray[buttonTag-1] font:labelFont];
        labelHeightWithFont = boundingRect.size.height;
        // Loop until the text at the current size fits the maximum width/height.
    } while (labelHeightWithFont > [self buttonLabelMaxWidth]);

    buttonlabel.text = subcatbuttontitlesarray[buttonTag-1];
    buttonlabel.font = labelFont;

- (CGRect)boundingRectForString:(NSString *)string font:(UIFont *)font
 {

return [string boundingRectWithSize:CGSizeMake([self buttonLabelMaxWidth], MAXFLOAT)
                                      options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
                                   attributes:@{NSFontAttributeName: font}
                                      context:nil];
 }



- (CGFloat)buttonLabelMaxWidth
      {
   CGFloat hypotenuse = CGRectGetWidth(CGRectMake(0, 0, 60, 60));
   CGFloat rightTriangleCathetus = sqrtf((hypotenuse*hypotenuse)/2);
   return rightTriangleCathetus;
      }

我在这里找到了这个帖子:

iOS7 - Adjusting font size of multiline label to fit its frame

有同样的问题。

编辑2:

在搜索了整整一天的解决方案并尝试了标签属性的各种组合之后,我以某种方式想出“numberoflines”是我的罪魁祸首。所以我想出了这个愚蠢的解决方案,计算字符串中的单词,并根据字符串的数量调整行数:

    NSString *samplestring = @"Three words string";
//Count the words in this string
int times = [[samplestring componentsSeparatedByString:@" "] count]-1;

UILabel *testlabel = [[UILabel alloc]initWithFrame:CGRectMake(30, 30, 60, 60)];
[testlabel setText:samplestring];



[testlabel setFont:[UIFont fontWithName:@"HelveticaNeue-UltraLight" size:40.0f]];
[testlabel setBackgroundColor:[UIColor redColor]];

 [testlabel setAdjustsFontSizeToFitWidth:YES];
  [testlabel setTextAlignment:NSTextAlignmentCenter];

//My workaround
if(times ==0){
[testlabel setNumberOfLines:1];
}else{
    if(times==1){
        [testlabel setNumberOfLines:2];
    }
        else{
            [testlabel setNumberOfLines:3];
        }}




 [self.view addSubview:testlabel];

2 个答案:

答案 0 :(得分:2)

我想你要做的是向NSString询问boundingRectWithSize:options:attributes:context:。通过设置边界矩形的宽度,您可以找出高度。您可以使用圆的参数公式来确定该边界矩是否完全适合圆的中心。不幸的是,您将不得不执行一种近似的试错序列,其中文本越来越大,直到顶部和底部伸出圆圈,然后缩小建议的宽度,看看是否会导致高度增长太多,因为文本现在需要额外的时间。

答案 1 :(得分:1)

假设您有一个自定义视图,您可以在其中绘制适合其框架的圆圈(在您的示例中为80x80)。

首先,您需要找到标签可以使用的最大宽度,而不会穿过圆圈的字母:

- (CGFloat)buttonLabelMaxWidth
{
    CGFloat hypotenuse = CGRectGetWidth(self.bounds);
    CGFloat rightTriangleCathetus = sqrtf((hypotenuse*hypotenuse)/2);
    return floorf(rightTriangleCathetus);
}

接下来,当您将标题传递给显示时,您需要通过减少最初超大的字体进行迭代,直到生成的字符串边界符合先前计算的宽度(这也是最大高度,因为它是一个圆圈)。 更新:您还需要检查标题中的每个字词,以确保它们没有被截断(它们符合最大宽度)。

- (void)setButtonTitle:(NSString *)title
{
    CGFloat fontSize = 20; // The max font size you want to use
    CGFloat minimumFontSize = 5; // The min font size you want to use
    CGFloat labelHeightWithFont = 0;
    CGFloat longestWordWidth = 0;
    UIFont *labelFont = nil;

    CGFloat buttonLabelMaxWidth = [self buttonLabelMaxWidth];

    do {

        if (fontSize < minimumFontSize) {
            // Handle exception where the title just won't fit
            break;
        }

        // Trying the current font size if it fits
        labelFont = [UIFont systemFontOfSize:fontSize--];
        CGSize boundingSize = [self boundingSizeForString:title font:labelFont];
        labelHeightWithFont = boundingSize.height;

        // Be sure that words are not truncated (that they fits in the maximum width)
        longestWordWidth = 0;
        for (NSString *word in [title componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]) {
            CGSize wordSize = [word sizeWithAttributes:@{NSFontAttributeName: labelFont}];
            longestWordWidth = MAX(longestWordWidth, wordSize.width);
        }

        // Loop until the text at the current size fits the maximum width/height.
    } while (labelHeightWithFont > buttonLabelMaxWidth || longestWordWidth > buttonLabelMaxWidth);

    self.buttonLabel.text = title;
    self.buttonLabel.font = labelFont;
}

- (CGSize)boundingSizeForString:(NSString *)string font:(UIFont *)font
{

    CGRect boundingRect = [string boundingRectWithSize:CGSizeMake([self buttonLabelMaxWidth], MAXFLOAT)
                                options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
                             attributes:@{NSFontAttributeName: font}
                                context:nil];
    return CGSizeMake(ceilf(boundingRect.size.width), ceilf(boundingRect.size.height));
}