Vorrei aggiungere i miei pensieri poiché ho avuto esattamente lo stesso problema.
Lo stavo usando UITextView
perché aveva un allineamento del testo più gradevole (giustificato, che al momento non era disponibile in UILabel
), ma per "simulare" non interattivo-non scorrevole UILabel
, disattivavo completamente lo scorrimento, il rimbalzo e l'interazione dell'utente .
Ovviamente, il problema era che il testo era dinamico e, sebbene la larghezza fosse fissa, l'altezza doveva essere ricalcolata ogni volta che avevo impostato un nuovo valore di testo.
boundingRectWithSize
per me non ha funzionato affatto bene, da quello che ho potuto vedere, è UITextView
stato aggiungere un margine in più che boundingRectWithSize
non avrebbe contato, quindi l'altezza recuperata boundingRectWithSize
era più piccola di quanto dovrebbe essere.
Dato che il testo non doveva essere aggiornato rapidamente, viene utilizzato solo per alcune informazioni che potrebbero aggiornarsi di più ogni 2-3 secondi, ho deciso il seguente approccio:
/* 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 );
}
* Il codice sopra non viene copiato direttamente dalla mia fonte, ho dovuto modificarlo / cancellarlo da un sacco di altre cose non necessarie per questo articolo. Non prenderlo per copia-incolla-e-esso-funzionerà-codice.
Lo svantaggio evidente è che ha allocazione e rilascio, per ogni chiamata.
Ma il vantaggio è che si evita a seconda della compatibilità tra il modo in cui boundingRectWithSize disegna il testo e calcola le dimensioni e l'implementazione del disegno del testo UITextView
(o UILabel
che è possibile utilizzare anche solo UITextView
con Sostituisci UILabel
). In questo modo si evitano eventuali "bug" che Apple potrebbe avere.
PS Sembrerebbe che non dovresti aver bisogno di questo "temp" UITextView
e puoi semplicemente chiedere sizeThatFits
direttamente dal target, tuttavia non ha funzionato per me. Sebbene la logica direbbe che dovrebbe funzionare e allocare / rilasciare il temporaneo UITextView
non è necessario, non lo ha fatto. Ma questa soluzione ha funzionato perfettamente per qualsiasi testo che avrei inserito.
lineBreakMode
?