web-dev-qa-db-fra.com

Comment déterminer la hauteur UIWebView en fonction du contenu, au sein d'une hauteur variable UITableView?

J'essaie de créer un UITableView avec des lignes de hauteur variable comme expliqué dans la réponse à cette question

Mon problème est que chaque cellule contient un UIWebView avec un contenu différent (chargé statiquement) Je ne peux pas comprendre comment calculer la bonne hauteur en fonction du contenu. Y a-t-il un moyen de faire cela? J'ai essayé des choses comme ça:

   (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
       WebViewCell *cell = (WebViewCell*)[self tableView:tableView cellForRowAtIndexPath:indexPath];
       [cell setNeedsLayout];
       [cell layoutIfNeeded];
       return cell.bounds.size.height;
    }

Les cellules elles-mêmes sont chargées à partir d'une plume, qui est simplement un UITableViewCell contenant un UIWebView. (Ce serait aussi bien si les cellules se réglaient simplement sur le plus grand du contenu html, bien que la hauteur variable soit plus agréable).

69
frankodwyer

Ce code est probablement trop lent pour une utilisation en vue tableau, mais fait l'affaire. Il ne semble pas y avoir d'alternative, car UIWebView n'offre aucun accès direct au DOM.

Dans un contrôleur de vue viewDidLoad je charge du code HTML dans une vue Web et lorsque le chargement est terminé, exécutez du javascript pour renvoyer la hauteur de l'élément.

- (void)viewDidLoad
{
    [super viewDidLoad];
    webview.delegate = self;
    [webview loadHTMLString:@"<div id='foo' style='background: red'>The quick brown fox jumped over the lazy dog.</div>" baseURL:nil];
}

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    NSString *output = [webview stringByEvaluatingJavaScriptFromString:@"document.getElementById(\"foo\").offsetHeight;"];
    NSLog(@"height: %@", output);
}
77
duncanwilcox

J'étais très heureux de trouver vos réponses, l'astuce javascript a bien fonctionné pour moi.

Cependant, je voulais dire qu'il existe également la méthode "sizeThatFits:":

CGSize goodSize = [webView sizeThatFits:CGSizeMake(anyWidth,anyHeigth)];

Nous devons définir une taille préférée différente de zéro, mais à part cela, cela fonctionne généralement toujours!

Habituellement, car avec les UIWebViews, il semble fonctionner uniquement sur le deuxième chargement (j'utilise la méthode "loadHTMLString:", et oui j'appelle "sizeThatFits:" à partir du délégué "méthode didFinishLoad:").

C'est pourquoi j'ai été très heureux de trouver votre solution qui fonctionne dans tous les cas.

28
Unfalkster

Cela semble fonctionner. Pour l'instant.

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    CGFloat webViewHeight = 0.0f;
    if (self.subviews.count > 0) {
        UIView *scrollerView = [self.subviews objectAtIndex:0];
        if (scrollerView.subviews.count > 0) {
            UIView *webDocView = scrollerView.subviews.lastObject;
            if ([webDocView isKindOfClass:[NSClassFromString(@"UIWebDocumentView") class]])
                webViewHeight = webDocView.frame.size.height;
        }
    }
}

Il doit retourner en toute sécurité 0 en cas d'échec.

6
Dave Batton

Le problème avec -sizeThatFits: est que cela ne fonctionne pas dès le départ, du moins pas sur iOS 4.1. Il renvoie simplement la taille actuelle de la webView (qu'elle soit appelée avec CGSizeZero ou une taille arbitraire non nulle).

J'ai découvert que cela fonctionne si vous réduisez la hauteur du cadre de la webView avant d'appeler -sizeThatFits:.

Voir ma solution: Comment déterminer la taille du contenu d'un UIWebView?

4
Ortwin Gentz

Si vous avez de mauvaises valeurs avec sizeThatFits la première fois mais pas après, voici une cause possible que j'ai rencontrée: un bug avec CSS externe. Il semble que webViewDidFinisLoad soit appelé bientôt, avant que le CSS externe ne soit récupéré et que le document Web soit entièrement construit. Je pense que le bug disparaît si vous rechargez à cause du cache.

Une astuce: préchargez votre CSS avec un UIWebView factice bientôt dans votre application.

SDK: IOS4

3
Kabhal

la mesure d'une vue Web fonctionne mais uniquement lorsqu'elle a chargé son contenu

  • rendre la vue Web petite (comme 5 pixels)
  • chargez-le et attendez la fin
  • appeler sizeToFit dessus alors
  • obtenir la taille ALORS
  • recharger la table (renvoyer la hauteur correcte pour la cellule)

publicité:: D voir ma classe M42WebviewTableViewCell sur github qui a du mal avec ça

3
Daij-Djan

La meilleure approche consiste à utiliser scrollView.contentSize.height propriété, comme ci-dessous.

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
     NSLog(@"%f",webView.scrollView.contentSize.height);   
}
2
Ans