IPhone UILabel sizeWithFont:

I am trying to measure the visual size of an NSString, which takes into account the number of rows that I can display. However, sizeWithFont does not account for the numberOfLines property? Therefore, my layout algorithm positions everything lower than they really should be.

_price = [[UILabel alloc] init];
_price.text = myPriceValue;
_price.lineBreakMode = UILineBreakModeWordWrap;
_price.numberOfLines = 3;
_price.backgroundColor = [UIColor clearColor];
_price.textColor = TTSTYLEVAR(colorPrice);
/// the follow code ignores numberOfLines and just tells me the size of the whole block.  
// I'd like it to be aware of numberOfLines
//
CGSize priceSize = [_price.text sizeWithFont:_price.font
        constrainedToSize:CGSizeMake(maxWidth, CGFLOAT_MAX)
        lineBreakMode:UILineBreakModeWordWrap];

Does anyone know how to do this using the iPhone SDK?

+5
source share
5 answers

Instead of CGFLOAT_MAX for the maximum height of your textual calculation, try to get the size of one line with this:

[_price.text sizeWithFont:_price.font].height

and then multiplying this by the maximum number of rows you want, then connect this to the height of your size. It probably looks like this:

_price = [[UILabel alloc] init];
_price.text = myPriceValue;
_price.lineBreakMode = UILineBreakModeWordWrap;
_price.numberOfLines = 3;
_price.backgroundColor = [UIColor clearColor];
_price.textColor = TTSTYLEVAR(colorPrice);
CGFloat lineHeight = [_price.text sizeWithFont:_price.font].height;
CGSize priceSize = [_price.text sizeWithFont:_price.font
        constrainedToSize:CGSizeMake(maxWidth, lineHeight * _price.numberOfLines)
        lineBreakMode:UILineBreakModeWordWrap];

, 0, 0 ; CGFLOAT_MAX.

+12

UILabel sizeToFit sizeWithFont: UILabel, sizeWithFont: (. apple docs). , ... , :

-(void)setFontSizeOfMultiLineLabel: (UILabel*)label 
        toFitSize: (CGSize) size 
        forMaxFontSize: (CGFloat) maxFontSize 
        andMinFontSize: (CGFloat) minFontSize 
        startCharacterWrapAtSize: (CGFloat)characterWrapSize{

CGRect constraintSize = CGRectMake(0, 0, size.width, 0);
label.frame = constraintSize;
label.lineBreakMode = UILineBreakModeWordWrap;
label.numberOfLines = 0; // allow any number of lines

for (int i = maxFontSize; i > minFontSize; i--) {

    if((i < characterWrapSize) && (label.lineBreakMode == UILineBreakModeWordWrap)){
        // start over again with lineBreakeMode set to character wrap 
        i = maxFontSize;
        label.lineBreakMode = UILineBreakModeCharacterWrap;
    }

    label.font = [label.font fontWithSize:i];
    [label sizeToFit];
    if(label.frame.size.height < size.height){
        break;
    }       
    label.frame = constraintSize;
  } 
}

:

UILabel *label = [[UILabel alloc] initWithFrame: CGRectZero];   
label.backgroundColor = [UIColor clearColor];   
label.textColor = [UIColor whiteColor];
label.text = text;
label.font = [UIFont fontWithName: @"Helvetica" size: 16];
[self setFontSizeOfMultiLineLabel: label toFitSize: CGSizeMake(200, 44) forMaxFontSize: 16 andMinFontSize: 8 startCharacterWrapAtSize: 11]; 

startCharacterWrapAtSize characterWrap, . , wordWrap .

edit: bugfix

+5

, , - ( , ):

NSString *s = _price.text;
UIFont *font = _price.font;
CGFloat fontSize = font.pointSize;

while (TRUE)
{
   CGSize priceSize = [s sizeWithFont: font constrainedToSize: 
       CGSizeMake(maxWidth, fontSize) lineBreakMode: UILineBreakModeWordWrap];

    if ( /* priceSize is satisfactory */ )
    {
        break; // Make sure this exits, eventually!!!
    }
    fontSize -= 1.0; // or a smaller decrement if you like
    font = // new, smaller font

}
0

, , numberOfLines 0, , . . .

0

, , , , . , . , .

I am not sure what your problem is; Are you getting size too tall or too short, or what? You can find out the number of lines of text by dividing the height of the result by the height of the font, which, I believe, is the clamp value plus the trigger.

-1
source

All Articles