2012-06-22 36 views
5

我有4行UILabel與確切的框架和字體。如何知道NSString是否適合UILabel以及是否適合最後一個字符串的索引?

我需要知道這個字符串是否符合標籤,最後一個符合的索引是什麼。

+3

這個問題應該可以幫到你: http://stackoverflow.com/questions/6422742/how-to-know-the-length-of-nsstring-that-fits-a-uilabel-with-fixed-size –

+0

我曾經看過這個第一次,但它並沒有幫助 –

+0

答案@Cupcake貼在這裏應該幫助你 –

回答

8

答案的核心在Cupcake的引用文章中。無論如何,你可以使用sizeWithFont:constrainedToSize:lineBreakMode:來給出一個特定的文字環繞,例如給定寬度的標籤中的特定字體的幀尺寸。

CGSize size = [string sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:UILineBreakModeWordWrap]; 

設置sizeConstraint是你的標籤寬度相同,但設定的高度要大一些。如果生成的size.height比您的UILabel大,那麼您的字符串太長。理論上,您可以刪除最後一個字符/單詞,然後重試並重復,直到適合。

如果您認爲這些字符串可能很長,您可能需要換個角度,先從字符串的一小部分開始,然後繼續添加字符,直到字符太大,然後您就知道最後一個字符。

無論哪種方式,這種迭代計算的大小可以相當cpu密集型操作,所以要小心。

更新:

這裏是返回的NSString的長度,可以使用默認的字體(但忽略最小字體大小)融入問題的UILabel的算法:

- (NSUInteger)fitString:(NSString *)string intoLabel:(UILabel *)label 
{ 
    UIFont *font   = label.font; 
    UILineBreakMode mode = label.lineBreakMode; 

    CGFloat labelWidth  = label.frame.size.width; 
    CGFloat labelHeight = label.frame.size.height; 
    CGSize sizeConstraint = CGSizeMake(labelWidth, CGFLOAT_MAX); 

    if ([string sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:mode].height > labelHeight) 
    { 
     NSString *adjustedString; 

     for (NSUInteger i = 1; i < [string length]; i++) 
     { 
      adjustedString = [string substringToIndex:i]; 

      if ([adjustedString sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:mode].height > labelHeight) 
       return i - 1; 
     } 
    } 

    return [string length]; 
} 

你例如,如果你檢查了單詞分隔模式,跳轉到下一個單詞分隔符,然後調用sizeWithFont,但是對於小的UILabel,這可能會使這更有效。如果你想利用自動換邏輯,以儘量減少你打電話sizeWithFont的次數,你可能有這樣的:

- (NSUInteger)fitString:(NSString *)string intoLabel:(UILabel *)label 
{ 
    UIFont *font   = label.font; 
    UILineBreakMode mode = label.lineBreakMode; 

    CGFloat labelWidth  = label.frame.size.width; 
    CGFloat labelHeight = label.frame.size.height; 
    CGSize sizeConstraint = CGSizeMake(labelWidth, CGFLOAT_MAX); 

    if ([string sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:mode].height > labelHeight) 
    { 
     NSUInteger index = 0; 
     NSUInteger prev; 
     NSCharacterSet *characterSet = [NSCharacterSet whitespaceAndNewlineCharacterSet]; 

     do 
     { 
      prev = index; 
      if (mode == UILineBreakModeCharacterWrap) 
       index++; 
      else 
       index = [string rangeOfCharacterFromSet:characterSet options:0 range:NSMakeRange(index + 1, [string length] - index - 1)].location; 
     } 
     while (index != NSNotFound && index < [string length] && [[string substringToIndex:index] sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:mode].height <= labelHeight); 

     return prev; 
    } 

    return [string length]; 
} 

也許這裏使用的字符集是不完全正確(應包括連字符,用於例如),但如果您不需要這樣做,它可能非常接近並且比逐個角色更有效率。

+0

真的謝謝你! –

+3

現在不推薦使用此方法,因此您可以使用 - (CGRect)boundingRectWithSize :(CGSize)大小選項:(NSStringDrawingOptions)選項上下文:(NSStringDrawingContext *)上下文NS_AVAILABLE_IOS(6_0);改爲 – Will