2013-05-24 11 views
5

Ok, so che questa domanda è stata posta e posta. Ci sono molti buoni suggerimenti, ma non riesco a farlo funzionare come previsto. Sto cercando di creare una cella tableview in grado di impostare dinamicamente la sua altezza sul carico in base a diversi html. Quello che tutti suggeriscono è usare il seguente metodo.Determina l'altezza di UIWebView in base al contenuto locale dinamico, all'interno di un'altezza variabile. TableViewCell

-(void)webViewDidFinishLoad:(UIWebView *)webView 

Dicono per calcolare l'altezza sia utilizzando JavaScript come di seguito:

NSString *output = [webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight;"]; 

o fare qualcosa di simile (ho creato questo):

self.webView = webView; 
CGRect frame = webView.frame; 
frame.size.height = 1; 
webView.frame = frame; 
CGSize fittingSize = [webView sizeThatFits:CGSizeZero]; 
frame.size = fittingSize; 
webView.frame = frame; 

Entrambi questi metodi restituiscono il altezza corretta della webview, ma avvengono dopo l'inizializzazione della tableview. Questo webViewDidFinishLoad viene chiamato dopo il metodo heightForRowAtIndexPath. Quindi, quando il tavolo è in costruzione, non ho l'altezza della cella. Quindi tutti dicono bene, quindi basta fare una tableview per ricaricarsi all'interno del tuo webViewDidFinishLoad che funziona ancora, ma non mi piace perché c'è un ritardo e rende lo scrolling del tableview choppy quando arrivi a quella parte. Come posso risolvere questo? E renderlo liscio? Stavo pensando di determinare in qualche modo l'altezza della webview prima di caricare la vista, ma non sono sicuro di come lo farei. Ho anche provato a convertire l'html in una stringa di testo semplice, ma questo si traduce in un'altezza falsa perché l'html ha spazi e cose mentre il testo normale non lo fa. Qualsiasi aiuto sarebbe apprezzato!

+1

Puoi caricare la visualizzazione Web off-screen abbastanza presto in modo che sia probabile che sia finito prima heightForRowAtIndexPath viene chiamato? Inoltre, hai determinato la natura del ritardo e del choppiness? Forse quel problema può essere risolto. –

+0

Ottima idea! Questo è quello che ho finito per fare. – mikemike396

risposta

3

Il mio suggerimento è molto simile a @Timothy Moose, rendendo la visualizzazione web fuori schermo.

L'approccio vorrei prendere qui sarebbe ...

-(void)viewDidLoad 
{ 
    //Create a UIWebView and store it in a property 
    //Hook the delegate to the view controller. 
    //Load the html string to the UIWebView. 

    //The rest of your initialization 
} 

In questo caso, il vostro heightForRowAtIndexPath: sarà ancora probabilmente ottenere chiamato prima del completamento della visualizzazione web.

È possibile gestirlo in due modi. Ecco un suggerimento.

Nel metodo delegato di UIWebView webViewDidFinishLoading, verificare che la webview che effettua la chiamata sia la webview memorizzata nella proprietà. In tal caso, chiama per ricaricare la sezione (o riga) in cui è contenuta la tua webview. Questo dovrebbe chiamare il metodo heightForRowAtIndexPath: per essere chiamato di nuovo, in questo caso, puoi memorizzare l'altezza della webview nel callback webViewDidFinishLoading.

Se la cella è fuori dello schermo quando la vista primi spettacoli, la cellula che si crea in cellForRowAtIndexPath:, dovrebbero avere la UIWebView che si è creato nel vostro viewDidLoad. A tale scopo, aggiungi UIWebView alla visualizzazione del contenuto della cella.

Se la cella è sullo schermo quando viene visualizzata la vista per la prima volta, suggerirei uno spinner di attività la prima volta che viene caricata la cella, quindi una volta terminata la sessione Web, ricaricare la cella con la visualizzazione Web.

+0

Ottima risposta! Questa sembrava essere l'unica soluzione che funzionava. Caricare la schermata Web fuori dallo schermo e quindi memorizzare l'altezza funziona perfettamente. L'unico problema che avevo era l'aggiunta della webview alla cella durante il metodo cellForRowAtIndex. – mikemike396

4

Alla fine della giornata non è possibile conoscere l'altezza del contenuto di una visualizzazione Web finché non viene caricata. E se lo stesso bit di codice sta configurando la tabella e caricando la webview, la webview completerà sempre il caricamento dopo che la tabella è già stata visualizzata.

Se si carica ripetutamente lo stesso codice HTML, è possibile memorizzare l'altezza nella cache, ma si verificherà ancora un problema la prima volta.

Quindi, l'unico modo per visualizzare la visualizzazione tabella scorrevole senza essere misti è di avere un'altezza di cella predefinita fino al caricamento della webview. Quindi cambialo. Ma ci hai provato, usando reload. E quello era mosso.

Ma che dire l'altezza della cella si anima tra l'altezza predefinita e l'altezza reale? Forse sarebbe più accettabile.

Se si stanno facendo solo variazioni di altezza, credo che si possa fare questo piuttosto che ricaricare, al fine di animare il ridimensionamento.

[tableView beginUpdates]; 
[tableView endUpdates]; 

Niente di necessario tra le due linee.

Forse potresti combinare questo con il caching della vera altezza del codice HTML per la prossima volta che l'utente lo fa scorrere in vista.

+0

Perfetto !! semplicemente perfetto. Saluti.! –

0

Nel tuo caso hai una webview in tableviewcell, quindi in heightForRowAtIndexPath puoi impostare l'altezza della cella in altezza della dimensione NSAttributoString come segue.

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 


    NSAttributedString *attributedText = [NSString getHTMLAttributedString:@"HTML Content"]; 
    CGSize size = CGSizeMake(300, CGFLOAT_MAX); 
    CGRect paragraphRect =  [attributedText boundingRectWithSize:size 
           options:(NSStringDrawingUsesLineFragmentOrigin) 
           context:nil]; 
    return paragraphRect.size.height; 
} 

+(NSAttributedString *) getHTMLAttributedString:(NSString *) string{ 
    NSError *errorFees=nil; 
    NSString *sourceFees = [NSString stringWithFormat: 
          @"<span style=\"font-family: 'Roboto-Light';font-size: 14px\">%@</span>",string]; 
    NSMutableAttributedString* strFees = [[NSMutableAttributedString alloc] initWithData:[sourceFees dataUsingEncoding:NSUTF8StringEncoding] 
                       options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, 
                          NSCharacterEncodingDocumentAttribute: [NSNumber numberWithInt:NSUTF8StringEncoding]} 
                     documentAttributes:nil error:&errorFees]; 
    return strFees; 

} 
Problemi correlati