2013-05-24 2 views
5

Okay, ich weiß, diese Frage wurde gestellt und gefragt. Es gibt viele gute Vorschläge, aber ich kann nicht wie erwartet funktionieren. Ich versuche, eine Tableview-Zelle zu erstellen, die ihre Höhe dynamisch auf der Grundlage von unterschiedlichem HTML festlegen kann. Was jeder vorschlägt, ist die folgende Methode.Bestimmen UIWebView Höhe basierend auf dynamischen lokalen Inhalt, innerhalb einer Variablenhöhe TableViewCell

-(void)webViewDidFinishLoad:(UIWebView *)webView 

sagen Sie die Höhe berechnen entweder mit Hilfe von Javascript wie folgt:

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

Oder so etwas wie dies zu tun (ich diese erstellt):

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; 

die beiden Methoden zurückkehren korrekte Höhe der Webansicht, aber sie treten auf, nachdem die Tabellenansicht initialisiert wurde. Dieses webViewDidFinishLoad wird nach der heightForRowAtIndexPath-Methode aufgerufen. Also, wenn der Tisch gebaut wird, habe ich nicht die Höhe der Zelle. Also dann sagen alle gut, dann machen Sie einfach eine Tabellenansicht in Ihrem webViewDidFinishLoad neu laden, die wieder funktioniert, aber ich mag das nicht, weil es eine Verzögerung gibt und es das Blättern der Tabellenansicht abgehackt macht, wenn Sie zu diesem Teil kommen. Wie kann ich das beheben? Und mach es glatt? Ich überlegte, ob ich vielleicht die Höhe der Webansicht bestimmen sollte, bevor ich die Ansicht geladen habe, aber ich bin mir nicht sicher, wie ich das machen würde. Es wurde auch versucht, den HTML-Code in eine reine Textzeichenfolge umzuwandeln, aber dies führt zu einer falschen Höhe, da der HTML-Code Leerzeichen und andere Zeichen enthält, während der Klartext dies nicht tut. Jede Hilfe wäre willkommen!

+1

Können Sie die Web-Ansicht außerhalb des Bildschirms früh genug laden, so dass sie wahrscheinlich beendet wird, bevor heightForRowAtIndexPath aufgerufen wird? Haben Sie auch die Art der Verzögerung und der Rauheit festgestellt? Vielleicht kann dieses Problem gelöst werden. –

+0

Großartige Idee! Das ist, was ich getan habe. – mikemike396

Antwort

3

Mein Vorschlag ist sehr ähnlich zu @Timothy Moose, indem das Webview vom Bildschirm gerendert wird.

Der Ansatz, den ich hier ...

-(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 diesem Fall wäre nehmen würde, wird Ihre heightForRowAtIndexPath: wahrscheinlich immer noch vor der Fertigstellung der Web-Ansicht aufgerufen.

Sie können das auf verschiedene Arten handhaben. Hier ist ein Vorschlag.

Überprüfen Sie in der Delegate-Methode des UIWebView webViewDidFinishLoading, ob die Webansicht, die den Aufruf ausführt, die in Ihrer Property gespeicherte Webansicht ist. Wenn dies der Fall ist, rufen Sie den Abschnitt (oder die Zeile) auf, in dem Ihr Webview enthalten ist. Dies sollte die Methode heightForRowAtIndexPath: aufrufen, um erneut aufgerufen zu werden. In diesem Fall können Sie die Höhe des Webview im Rückruf webViewDidFinishLoading speichern.

Wenn die Zelle bei Anzeige der Ansicht nicht angezeigt wird, sollte die in cellForRowAtIndexPath: erstellte Zelle die UIWebView haben, die Sie in Ihrer viewDidLoad erstellt haben. Tun Sie dies, indem Sie die UIWebView der Inhaltsansicht der Zelle hinzufügen.

Wenn die Zelle auf dem Bildschirm angezeigt wird, wenn die Ansicht zuerst angezeigt wird, würde ich beim ersten Laden der Zelle einen Aktivitätsschalter vorschlagen. Laden Sie die Zelle nach dem Laden der Webansicht erneut mit der Webansicht.

+0

Große Antwort! Dies schien die einzige Lösung zu sein, die funktionierte. Das Laden der webView off-Bildschirm und das Speichern der Höhe funktioniert perfekt. Das einzige Problem, das ich hatte, war, während der cellForRowAtIndex-Methode die Webansicht wieder in die Zelle einzufügen. – mikemike396

4

Am Ende des Tages können Sie nicht wissen, wie hoch der Inhalt einer Webansicht ist, bis sie geladen wird. Und wenn derselbe Code die Tabelle aufsetzt und die Webansicht lädt, wird die Webansicht immer fertig geladen, nachdem die Tabelle bereits angezeigt wurde.

Wenn Sie wiederholt denselben HTML-Code laden, können Sie die Höhe zwischenspeichern, aber Sie haben beim ersten Mal noch ein Problem.

Die einzige Möglichkeit, die Scroll-Tabellenansicht anzuzeigen, ohne abgehackt zu sein, besteht darin, eine Standard-Zellenhöhe zu haben, bis die Webansicht geladen ist. Dann ändere es. Aber Sie haben das mit reload versucht. Und das war abgehackt.

Aber was ist mit der Zellenhöhe animiert zwischen der Standardhöhe und der wahren Höhe? Vielleicht wäre das akzeptabler.

Wenn Sie nur Höhenänderungen vornehmen, glaube ich, dass Sie dies tun können, anstatt neu zu laden, um die Größenänderung zu animieren.

[tableView beginUpdates]; 
[tableView endUpdates]; 

Nichts zwischen den beiden Linien benötigt.

Vielleicht könnten Sie dies kombinieren mit Caching die wahre Höhe des HTML für das nächste Mal der Benutzer scrollt es in Sicht.

+0

Perfekt !! einfach perfekt. Prost.! –

0

In Ihrem Fall haben Sie webview in tableviewcell, also in heightForRowAtIndexPath legen Sie die Höhe der Zelle auf Höhe der NSAttributedString Größe wie folgt.

-(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; 

}