Determine la altura de UIWebView en function del contenido local dynamic, dentro de una altura variable TableViewCell

De acuerdo, entonces sé que esta pregunta se ha hecho y se ha preguntado. Hay muchas buenas sugerencias, pero no puedo hacer que esto funcione como se esperaba. Estoy intentando crear una celda tableview que pueda establecer dinámicamente su altura en la carga basada en diferentes html. Lo que todo el mundo sugiere es usar el siguiente método.

-(void)webViewDidFinishLoad:(UIWebView *)webView 

Dicen que para calcular la altura usando javascript de la siguiente manera:

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

O haciendo algo como esto (creé esto):

 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; 

Ambos methods devuelven la altura correcta de la vista web, pero ocurren después de inicializar la vista de tabla. Este webViewDidFinishLoad se invoca después del método heightForRowAtIndexPath. Entonces, cuando se está construyendo la tabla, no tengo la altura de la celda. Entonces todo el mundo dice bien y luego hace una recarga de vista de tabla dentro de su webViewDidFinishLoad, que funciona una vez más, pero no me gusta porque hay un retraso y hace que el desplazamiento de la tabla se vea entrecortado cuando se llega a esa parte. ¿Cómo puedo arreglar esto? ¿Y hacerlo suave? Estaba pensando quizás de alguna forma determinar la altura de la vista web antes de cargar la vista, pero no estoy seguro de cómo lo haría. También intentó convertir el html en una cadena de text sin formatting, pero esto da como resultado una altura falsa porque el html tiene espacios y cosas, mientras que el text sin formatting no. ¡Cualquier ayuda sería apreciada!

Mi sugerencia es muy similar a @Timothy Moose, al mostrar la vista web fuera de la pantalla.

El enfoque que tomaría aquí sería …

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

En este caso, your heightForRowAtIndexPath: probablemente aún será llamado antes de completar la vista web.

Puede manejar eso de varias maneras. Aquí hay una sugerencia.

En el método de delegado de webViewDidFinishLoading de webViewDidFinishLoading , verifique que la vista web que realiza la llamada sea la vista web almacenada en su propiedad. Si es así, llame para volver a cargar la sección (o fila) en que está contenida su vista web. Esto debería llamar al método heightForRowAtIndexPath: para volver a llamar, en este caso, puede almacenar la altura de la vista web en la webViewDidFinishLoading llamada webViewDidFinishLoading .

Si la celda está fuera de la pantalla cuando la vista aparece por primera vez, la celda que se crea en cellForRowAtIndexPath: debe tener la UIWebView que creó en su viewDidLoad . Para ello, agregue UIWebView a la vista de contenido de la celda.

Si la celda está en la pantalla cuando la vista aparece por primera vez, sugeriría un spinner de actividad la primera vez que se cargue la celda, y luego una vez que se haya cargado la vista web, vuelva a cargar la celda con la vista web.

Al final del día, no puede conocer la altura del contenido de una webview hasta que se cargue. Y si el mismo bit de código está configurando la tabla y cargando la vista web, la vista web siempre va a completar su carga después de que la tabla ya se muestre.

Si carga repetidamente el mismo HTML, puede almacenar en caching la altura, pero aún así tendrá un problema la primera vez.

Por lo tanto, la única manera de que pueda mostrar la vista de tabla de desplazamiento sin ser entrecortada es tener una altura de celda pnetworkingeterminada hasta que se cargue la vista web. Luego cámbialo. Pero has intentado eso, usando la reload . Y eso fue entrecortado.

Pero, ¿qué ocurre con la altura de la celda entre la altura pnetworkingeterminada y la altura real? Tal vez eso sería más aceptable.

Si solo estás haciendo cambios de altura, creo que puedes hacer esto en lugar de volver a cargar, para animar el cambio de tamaño.

 [tableView beginUpdates]; [tableView endUpdates]; 

Nada necesario entre las dos líneas.

Tal vez podría combinar esto con el caching de la altura real del HTML para la próxima vez que el usuario lo desplace a la vista.

En su caso, tiene una vista web en tableviewcell, por lo tanto, en heightForRowAtIndexPath, establezca el alto de celda a alto del tamaño de NSAttributedString como sigue.

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