2010-02-25 11 views
15

C'è un modo per ottenere la dimensione corretta di un NSString utilizzando:sizeWithFont non dà giusta altezza per UITextView se v'è una lunga stringa nel testo di essere avvolto

- (CGSize)sizeWithFont:(UIFont *)font forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode 

che non ottiene gettato fuori dal 2 o trecento stringhe di caratteri. Al momento, se provo a utilizzare questo metodo su queste lunghe stringhe, le calcola erroneamente e alla fine di UITextView mi ritrovo con molti spazi bianchi.

Ho provato a utilizzare UILineBreakModeWordWrap e UILineBreakModeCharacterWrap.

il ridimensionamento è stato fatto in

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 
    CGFloat  result = 44.0f; 
    NSString* text = nil; 
    CGFloat  width = 0; 
    CGFloat  tableViewWidth; 
    CGRect  bounds = [UIScreen mainScreen].bounds; 

    tableViewWidth = bounds.size.width; 


    width = tableViewWidth - 150;  

    text = stringWithLongWords; 

    if (text) { 
     CGSize  textSize = { width, 20000.0f };  
     CGSize  size = [text sizeWithFont:[UIFont systemFontOfSize:10.0f] constrainedToSize:textSize lineBreakMode:UILineBreakModeWordWrap]; 

     size.height += 50.0f;    
     result = MAX(size.height, 44.0f+30.0f); 
    } 

    return result; 
} 
+0

Che cosa stai cercando di fare? Penso a sizeWithFont: funziona piuttosto bene, forse è come applichi queste informazioni a UITextView. Spiega per favore. –

+0

Ho una cella UITableView personalizzata con 2 UILabels e UITextView che utilizzano sizeWithFont per calcolare la dimensione necessaria per l'altezza della cella e della cella che a volte risulta essere superiore a 400 pixel. –

risposta

1

Hai detto che hai un UITableView con altezze diverse. Hai impostato l'identificativo di riutilizzo sulla stessa cosa per tutte le celle? Potrebbe essere che le celle più vecchie con la loro altezza già impostata vengano riutilizzate. Se questo è il problema, dovresti ridimensionare nuovamente la cella quando viene riutilizzata.

+0

C'è solo una cella di questo tipo su un UITableView, ho controllato per vedere se questo era un problema e non sembra esserlo. –

21

UITextView non è esattamente come un UILabel avvolto in un UIScrollView. Ha una spaziatura di riga diversa dalla dimensione e dai margini del font che non è responsabile di sizeWithFont:constrainedToSize:linkBreakMode:.

Conoscendo le dimensioni del carattere, è possibile calcolare il numero di linee e prendere in considerazione l'interlinea. Puoi indovinare ai margini e provare a ingannare sizeWithFont: per dare una risposta più utile.

Le soluzioni popolari sembrano essere:

  • basta usare un UILabel se non hai bisogno di alcuna funzionalità UITextView

  • se avete bisogno di hyperlinks, sovrapposizione UIButtons che assomigliano collegamenti ipertestuali nel corso di un UILabel

  • utilizzare uno schermo esterno UITextView e il suo metodo sizeToFit per ottenere un vero ans wer

Non ho avuto fortuna con la terza opzione ma sembra che dovrebbe funzionare, quindi forse ho fatto qualcosa di sbagliato.

Ho intenzione di provare a utilizzare uno UILabel e pulsanti sovrapposti per collegamenti ipertestuali. Vedremo come andrà a finire.

Se non funziona, c'è sempre l'opzione presa da Loren Brichter (di Tweetie fama): disegnare tutto in un UIView da soli, usando CoreGraphics.

Buona fortuna!

+2

La terza opzione probabilmente non funziona perché sizeToFit non funzionerà finché UITextView non verrà visualizzato sullo schermo. Solo un pensiero. – Quentamia

+0

Interessante. Mi chiedo se è possibile renderlo sullo schermo ma con alpha = 0 o qualcosa di molto basso per ingannarlo nel rendering ma ancora non visibile all'occhio umano. –

+0

Potrebbe funzionare e sarebbe un esperimento interessante. Mi piacerebbe trovare un modo per calcolare correttamente l'altezza prima del rendering però. Sarebbe molto utile quando UITextViews venisse utilizzato all'interno di UITableViewCells. – Quentamia

9

controllare questo post How do I size a UITextView to its content?

Sembra textView.contentSize.height dovrebbe funzionare (con l'avvertenza che il il contentSize corretta è disponibile solo dopo l'UITextView è stato aggiunto alla vista con addSubview)

1

La soluzione migliore che ho trovato finora è avere un UITextView nascosto separato con le stesse impostazioni di carattere e impostare il suo testo.Dopo che il suo contetSize dovrebbe essere accurato.

0

Ispirato @ risposta di MrNickBarker, ecco la mia soluzione:

CGFloat width = 280.0f; 

UITextView *t = [[UITextView alloc] init]; 
[t setFont:[UIFont systemFontOfSize:17]]; 
[label setText:@"some short or long text, works both"]; 

CGRect frame = CGRectMake(0, 0, width, 0); 
[t setFrame:frame]; 
// Here's the trick: after applying the 0-frame, the content size is calculated and can be used in a second invocation 
frame = CGRectMake(0, 0, width, t.contentSize.height); 
[t setFrame:frame]; 

L'unica questione in sospeso per me è che questo non funziona con inserti modificati.

ancora non posso credere sono richiesti torsioni, ma poiché -[NSString sizeWithFont:forWidth:lineBreakMode:] non rispetta inserti, imbottiture, margini, spaziature di riga e simili, sembra che questa è l'unica soluzione di lavoro al momento (cioè iOS 6).

1

La larghezza che si sta utilizzando è la larghezza per UITextView ... ma non si è interessati a tale larghezza, si è interessati alla larghezza dell'area di testo reale annidata all'interno della vista testo.

UITextViews, per impostazione predefinita, ha spaziatura attorno ai bordi per produrre uno spazio tra il testo digitato e il bordo di UITextView largo pochi pixel (e lungo per la parte superiore) ... Per ottenere la dimensione corretta si non dovrebbe usare

textView.frame.size.width

ma piuttosto,

textView.frame.size.width-(textView.contentInset.left+textView.contentInset.right+textView.textContainerInset.left+textView.textContainerInset.right+textView.textContainer.lineFragmentPadding/*left*/+textView.textContainer.lineFragmentPadding/*right*/)

^che prende la larghezza della UITextView e sottrae tutte le imbottiture così si sono lasciati wi la larghezza della sola area di testo in grado di scrivere.

Lo stesso vale per l'altezza ad eccezione di lineFragmentPadding non ha un fondale in modo da sottrarre solo una volta anziché due volte.


Il codice finale è qualcosa di simile:

CGSize textViewContentSize = CGSizeMake(theTextView.frame.size.width-(theTextView.contentInset.left+theTextView.contentInset.right+theTextView.textContainerInset.left+theTextView.textContainerInset.right+theTextView.textContainer.lineFragmentPadding/*left*/+theTextView.textContainer.lineFragmentPadding/*right*/), theTextView.frame.size.height-(theTextView.contentInset.top+theTextView.contentInset.bottom+theTextView.textContainerInset.top+theTextView.textContainerInset.bottom+theTextView.textContainer.lineFragmentPadding/*top*//*+theTextView.textContainer.lineFragmentPadding*//*there is no bottom padding*/)); 

    CGSize calculatedSize = [theTextView.text sizeWithFont:theTextView.font 
              constrainedToSize:textViewContentSize 
               lineBreakMode:NSLineBreakByWordWrapping]; 


    CGSize adjustedSize = CGSizeMake(ceilf(calculatedSize.width), ceilf(calculatedSize.height)); 
Problemi correlati