Gostaria de acrescentar meus pensamentos, já que tive exatamente o mesmo problema.
Eu estava usando, UITextView
pois 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.
boundingRectWithSize
não funcionou bem para mim, pelo que pude ver, UITextView
estava adicionando uma margem na parte superior que boundingRectWithSize
não entrava em contagem, portanto, a altura recuperada boundingRectWithSize
era 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 UILabel
o que também é possível utilizar apenas substituir UITextView
com UILabel
). Quaisquer "bugs" que a Apple possa ter são assim evitados.
PS: Parece que você não precisa desse "temp" UITextView
e pode apenas perguntar sizeThatFits
diretamente 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 UITextView
não é necessária, ela não funcionou. Mas essa solução funcionou perfeitamente para qualquer texto que eu inserisse.
lineBreakMode
?