Pergunta

Eu estou tentando medir o tamanho visual de um NSString que leva em conta o número de linhas que podem processar. No entanto, sizeWithFont não leva em conta propriedade numberOfLines? Assim, a minha disposição posições algoritmo tudo mais baixos do que realmente precisa ser.

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

Alguém sabe como fazer isso usando o iPhone SDK?

Foi útil?

Solução

Em vez de CGFLOAT_MAX para a altura máxima de seu cálculo de texto, tente obter o tamanho de uma linha com o seguinte:

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

e, em seguida, multiplicando que até o máximo # de linhas que você quer, então ligar que na altura do tamanho que você está restringindo-se a. Ele provavelmente ficaria assim:

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

Não use isso se você número cada vez conjunto de linhas para 0 como a sua altura máxima será de 0, nesse caso; você deve usar CGFLOAT_MAX então.

Outras dicas

SizeToFit vez de sizeWithFont Uso do UILabel: para o layout de um multi-line UILabel, desde sizeWithFont: vai truncar a string (ver docs maçã). O código a seguir reduz o tamanho da fonte de um rótulo até o ajuste de texto em um tamanho especificado ... várias linhas de texto serão utilizados tão logo eles se encaixam na altura especificada:

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

Chamar isso com um rótulo que tem o seu texto e fonte favorita:

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

O parâmetro startCharacterWrapAtSize permite optar por usar characterWrap começando no tamanho da fonte dar. Isso deve poupar espaço no caso wordWrap iria usar fontes muito pequenas.

edit: bugfix

Em vez de tentar fazê-lo em uma chamada, fazer algo como isto (desculpem o pseudocódigo, é tarde):

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

}

A resposta correta é, claro, você precisa numberOfLines definido como 0, o que fará com que o quadro para calcular o resultado com no entanto muitas linhas que necessita. Veja também esta questão .

É claro que ele não leva isso em conta, uma vez que nada está sendo chamado ou passado em tem essa informação. Você está trabalhando estritamente com cordas, tamanhos e fontes. É o rótulo que tem o número de linhas na mesma.

Eu não tenho certeza o que exatamente o seu problema é; você está recebendo um tamanho que é muito alto ou muito curto, ou o quê? Você pode descobrir o número de linhas de texto, dividindo a altura do resultado pela altura da fonte, que é o valor do ascender mais a descender, eu acredito.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top