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).
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);
}
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.
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.
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?
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
la mesure d'une vue Web fonctionne mais uniquement lorsqu'elle a chargé son contenu
publicité:: D voir ma classe M42WebviewTableViewCell sur github qui a du mal avec ça
La meilleure approche consiste à utiliser scrollView.contentSize.height
propriété, comme ci-dessous.
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSLog(@"%f",webView.scrollView.contentSize.height);
}