代码之家  ›  专栏  ›  技术社区  ›  CVertex

iPhone uiLabel SizeWithFont:

  •  5
  • CVertex  · 技术社区  · 15 年前

    我正在尝试测量nsstring的可视大小,它考虑了我可以呈现的行数。但是,sizeWithFont不考虑NumberOfLines属性?所以我的布局算法定位的所有东西都比实际需要的要低。

    _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];
    

    有人知道如何使用iPhone SDK来实现这一点吗?

    5 回复  |  直到 13 年前
        1
  •  12
  •   Kevlar    15 年前

    对于文本计算的最大高度,请尝试使用以下方法获取一行的大小,而不是cgfloat_max:

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

    然后把它乘以你想要的最大线数,然后把它插进你限制自己的高度。可能看起来像这样:

    _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;此时应使用cfloat_max。

        2
  •  5
  •   Felix    14 年前

    使用uiLabel的sizeToFit而不是sizeWithFont:来布局多行uiLabel,因为sizeWithFont:将截断字符串(请参见Apple文档)。以下代码将减小标签的字体大小,直到文本适合指定的大小…多行文本将在符合指定高度后立即使用:

    -(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]; 
    

    startcharacterwraptsize参数允许您选择从给定的字体大小开始使用characterwrap。这样可以节省空间,因为自动换行将使用非常小的字体。

    编辑:修复

        3
  •  0
  •   Amagrammer    15 年前

    不要在一个调用中尝试这样做(请原谅伪代码,这很晚了):

    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
    
    }
    
        4
  •  0
  •   Community Michael Schmitz    7 年前

    正确的答案是,当然,您需要将NumberOfLines设置为0,这将导致框架使用它需要的任意多行计算结果。也见 this question .

        5
  •  -1
  •   Ed Marty    15 年前

    当然,它没有考虑到这一点,因为任何被调用或传递的信息都没有。您严格使用字符串、大小和字体。标签上有行数。

    我不知道你的问题到底是什么;你穿的尺码是太高还是太短,还是什么?你可以通过将结果的高度除以字体的高度来找出文本的行数,我相信,字体的高度就是升序和降序的值。