Gostaria de acrescentar meus pensamentos, já que tive exatamente o mesmo problema.
Eu estava usando, UITextViewpois tinha um alinhamento de texto melhor (justifique, que no momento não estava disponível UILabel), mas para "simular" não interativo-não-rolável UILabel, eu desativaria completamente a interação de rolagem, salto e interação do usuário .
Obviamente, o problema era que o texto era dinâmico e, embora a largura fosse fixa, a altura deveria ser recalculada toda vez que eu definir um novo valor de texto.
boundingRectWithSizenão funcionou bem para mim, pelo que pude ver, UITextViewestava adicionando uma margem na parte superior que boundingRectWithSizenão entrava em contagem, portanto, a altura recuperada boundingRectWithSizeera menor do que deveria.
Como o texto não deveria ser atualizado rapidamente, ele é usado apenas para algumas informações que podem ser atualizadas a cada 2-3 segundos, decidi a seguinte abordagem:
/* This f is nested in a custom UIView-inherited class that is built using xib file */
-(void) setTextAndAutoSize:(NSString*)text inTextView:(UITextView*)tv
{
CGFloat msgWidth = tv.frame.size.width; // get target's width
// Make "test" UITextView to calculate correct size
UITextView *temp = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, msgWidth, 300)]; // we set some height, really doesn't matter, just put some value like this one.
// Set all font and text related parameters to be exact as the ones in targeted text view
[temp setFont:tv.font];
[temp setTextAlignment:tv.textAlignment];
[temp setTextColor:tv.textColor];
[temp setText:text];
// Ask for size that fits :P
CGSize tv_size = [temp sizeThatFits:CGSizeMake(msgWidth, 300)];
// kill this "test" UITextView, it's purpose is over
[temp release];
temp = nil;
// apply calculated size. if calcualted width differs, I choose to ignore it anyway and use only height because I want to have width absolutely fixed to designed value
tv.frame = CGRectMake(tv.frame.origin.x, tv.frame.origin.y, msgWidth, tv_size.height );
}
* O código acima não é copiado diretamente da minha fonte, eu tive que ajustá-lo / limpá-lo de várias outras coisas não necessárias para este artigo. Não aceite o código copiar-colar-e-ele-funcionará.
A desvantagem óbvia é que ele tem alocação e liberação para cada chamada.
Mas, a vantagem é que você evite dependendo da compatibilidade entre a forma como boundingRectWithSize desenha texto e calcula o seu tamanho e implementação de desenho de texto em UITextView(ou UILabelo que também é possível utilizar apenas substituir UITextViewcom UILabel). Quaisquer "bugs" que a Apple possa ter são assim evitados.
PS: Parece que você não precisa desse "temp" UITextViewe pode apenas perguntar sizeThatFitsdiretamente do alvo, mas isso não funcionou para mim. Embora a lógica diga que deve funcionar e que a alocação / liberação temporária UITextViewnão é necessária, ela não funcionou. Mas essa solução funcionou perfeitamente para qualquer texto que eu inserisse.
lineBreakMode?