调整UILabel的大小以适应Word Wrap

0x9*_*x90 6 iphone cocoa-touch word-wrap uikit uilabel

这是iPhone应用程序的一部分,但应该适用于一般用objC编写的Cocoa.

我有一个UILabel持有不同数量的文本(从单个字符到几个句子).文本应始终以适合UILabel中所有文本的最大可能字体显示.最大行数设置为4,换行模式设置为自动换行.

由于使用了多行,adjustsFontSizeToFitWidth将无法用于调整文本大小.

因此,我使用循环来确定每个字符串的最大可能字体大小:

    //Set the text  
    self.textLabel.text = text;
    //Largest size used  
    NSInteger fsize = 200;  textLabel.font = [UIFont
    fontWithName:@"Verdana-Bold"
    size:fsize];

    //Calculate size of the rendered string with the current parameters
    float height = [text sizeWithFont:textLabel.font
        constrainedToSize:CGSizeMake(textLabel.bounds.size.width,99999) 
        lineBreakMode:UILineBreakModeWordWrap].height;

    //Reduce font size by 5 while too large, break if no height (empty string)
    while (height > textLabel.bounds.size.height and height != 0) {   
        fsize -= 5;  
        textLabel.font = [UIFont fontWithName:@"Verdana-Bold" size:fsize];   
        height = [text sizeWithFont:textLabel.font 
            constrainedToSize:CGSizeMake(textLabel.bounds.size.width,99999) 
            lineBreakMode:UILineBreakModeWordWrap].height;
    };
Run Code Online (Sandbox Code Playgroud)

这种方法在大多数情况下都很有效.例外是长话.让我们来看一下@"体验foo".举个例子."经验"这个词比其他词长得多,将被分成两半,而不会被正确包装,并且字符串分为4行.我正在寻找一种方法来进一步减小尺寸,使每个单词适合一行.

例:

-旧-

字体大小:60

The
Exper
ience
foo
Run Code Online (Sandbox Code Playgroud)

应该

-新-

字体大小:30

The
Experience
foo
Run Code Online (Sandbox Code Playgroud)

可能有一种简单的方法可以做到这一点,但我正在撞墙.

0x9*_*x90 13

这是我发现的最优雅(但有点hackish)的方式:

  1. 将字符串拆分为单词
  2. 使用当前字体大小计算每个单词的宽度
  3. 减小字符串的大小,直到每个单词都适合一行

资源消耗足够低,即使在UITableViews以这种方式编辑的字符串中也可以工作.

这是新代码:

//Set the text  
self.textLabel.text = text;
//Largest size used  
NSInteger fsize = 200;  textLabel.font = [UIFont fontWithName:@"Verdana-Bold"
                                                         size:fsize];

//Calculate size of the rendered string with the current parameters
float height = 
      [text sizeWithFont:textLabel.font
       constrainedToSize:CGSizeMake(textLabel.bounds.size.width,99999) 
           lineBreakMode:UILineBreakModeWordWrap].height;

//Reduce font size by 5 while too large, break if no height (empty string)
while (height > textLabel.bounds.size.height and height != 0) {   
    fsize -= 5;  
    textLabel.font = [UIFont fontWithName:@"Verdana-Bold" size:fsize];   
    height = [text sizeWithFont:textLabel.font 
              constrainedToSize:CGSizeMake(textLabel.bounds.size.width,99999) 
                  lineBreakMode:UILineBreakModeWordWrap].height;
};

// Loop through words in string and resize to fit
for (NSString *word in [text componentsSeparatedByString:@" "]) {
    float width = [word sizeWithFont:textLabel.font].width;
    while (width > textLabel.bounds.size.width and width != 0) {
        fsize -= 3;
        textLabel.font = [UIFont fontWithName:@"Verdana-Bold" size:fsize];
        width = [word sizeWithFont:textLabel.font].width;

    }
}
Run Code Online (Sandbox Code Playgroud)