2009-03-14 7 views
16

Estoy construyendo una tabla con texto que es HTML, por lo que estoy usando un UIWebView como una subvista de mis celdas de tabla personalizadas. Ya me encontré con un problema: al desplazarme hacia abajo en la tabla, UIWebViews tardaría un segundo en actualizar. Por ejemplo, estaría viendo Células en las filas numeradas 1, 2 y 3. Me gustaría desplazarme hacia abajo para decir 8, 9 y 10. Por un momento, el contenido de la UIWebView que estaba visible en la celda n. ° 8 era el contenido de la celda n. ° 1, el contenido de la celda n. ° 9 fue el de la celda n. ° 2, y así sucesivamente.¿Cómo uso UIWebView en una celda de tabla?

Me enteré de que el problema era que UIWebViews simplemente procesaba el texto lentamente. Se sugirió cargar el contenido en el UIWebView en lugar de esperar hasta que la tabla reciba el cellForRowAtIndexPath. Entonces, ahora tengo un objeto de dominio que antes tenía el contenido de texto de WebView, pero ahora tiene una referencia a UIWebView.

Pero ahora parte del contenido de UIWebView se representa, y cuando me desplazo por la tabla, UIWebView se muestra solo como un cuadro gris. Si toco el cuadro gris, en realidad recibirá el toque y actualizará el WebView; por ejemplo, si toco un enlace (que puedo o no puedo hacer, dado que el cuadro es gris y lo sería por un golpe de suerte), la página que estaba vinculada se solicitará y se mostrará correctamente.

- (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier { 
if (self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) { 
      // I suppose this isn't necessary since I am just getting it from the 
      // Domain Object anyway 
    content = [[UIWebView alloc] initWithFrame:CGRectZero]; 
    content.backgroundColor = [UIColor blackColor]; 
    [self addSubview:content]; 
    [content release]; 
} 
return self; 
} 

// called by cellForRowAtIndexPath 
- (void)setMyDomainObject:(MyDomainObject*)anObject { 
UIWebView *contentWebView = anObject.contentWebView; 
int contentIndex = [self.subviews indexOfObject:content]; 
[self insertSubview:contentWebView atIndex:contentIndex]; 
} 

Respuesta

9

Una forma de lidiar con esto sería usar varios UILabels, cada uno con diferentes tipos de letra. Luego, colóquelos estratégicamente dentro de la celda para que parezcan texto contiguo. He visto esto hecho en una UITableView con muy buenos resultados.

Otro problema de rendimiento puede ser que está superando a UItableViewCell y su método init. Esto casi siempre conduce a un rendimiento pobre en una UITableView. En su lugar, solo use las instancias normales de UITableViewCell y agregue subvistas a su ContentView.

Esto ha sido ampliamente cubierto por Matt Gallagher's Easy Custom UITableView Drawing.

Otro método descrito fue el uso de Three20, que también puede proporcionarle texto con estilo.

Lo que está intentando actualmente no se puede hacer con UIWebview.

La precarga no ayudará: esto ralentizaría la interfaz de usuario cuando UIWebviews se muestren fuera de pantalla; siempre debes practicar la carga lenta en el iPhone.

Poner UIWebviews en una UITableView tendrá un impacto de rendimiento potencialmente inaceptable. Tendrá que usar otros medios para lograr su objetivo.

Desafortunadamente, NSAttributedString no está disponible en UIKit, lo que podría resolver fácilmente su problema.

+0

Terminé aceptando este b/c de la realidad de que esto no era algo que se puede hacer con un UIWebView. Personalmente, terminé abandonando la función, pero volveré a visitarla pronto, y lo que voy a hacer en lugar de usar TableView es simularlo usando HTML y CSS, y ponerlo en una sola WebView. Luego usaré WebViewDelegate para clasificar los clics de "interceptar" en los enlaces y determinar si mostrar otro contenido web o realizar alguna otra acción en mi aplicación. – bpapa

0

¿Ha considerado sobreescribir el método -prepareForReuse en su subclase de celda de tabla? Si las celdas no parecen actualizarse cuando se desplaza, es posible que el contenido de las celdas reutilizables no se borre y restablezca.

1

Dijiste 'llamado por setRowAtIndexPath', podrías querer decir 'cellForRowAtIndexPath' que es un método UITableView llamado cuando una fila se vuelve visible y necesita crear una celda. Asegúrese de que en este método esté inicializando y actualizando correctamente el contenido de la celda.

+0

Sí, estaba haciendo esto desde la memoria, que no es la mejor manera de escribir preguntas. – bpapa

+0

Puedes aclarar 'cuando empiece a desplazar las vistas web no actualizas'. ¿Estás desplazándote por la vista web o desplazándote por la vista de tabla? ¿Qué contenido hay en la vista web y en qué debería estar cambiando? – Akusete

+0

El tercer párrafo actualizado de la pregunta describe mejor lo que estoy viendo. – bpapa

2

Esto no responde a la pregunta original, pero retroceder un paso y mirar la imagen más grande, si está tratando de mostrar un hipervínculo en una celda de tabla, significa que cuando hace clic en él se abre un navegador web? ¿Sería lo mismo si mostrara texto con estilo en la celda de la tabla que parece o sugiere un enlace, pero abra una pantalla separada con una vista de web de pantalla completa que le permita tocar el enlace?

4

Si el contenido en la vista web se limita a texto o hipervínculos es posible que desee echar un vistazo al proyecto Three20 estilo: http://github.com/joehewitt/three20/tree/master

su clase TTStyledText tiene soporte para etiquetas <b>, <i>, <img>, and <a> en el contenido. Probablemente más ligero que las vistas web.

0

Según entiendo, una WebView no se procesará a menos que inicie la carga DESPUÉS de que viewDidLoad() ocurra.

+1

UIWebView parece hacer su renderizado después de que el control regrese al RunLoop principal, por lo que si intentas ejecutar JavaScript, no puedes hacerlo en - [viewDidLoad] o - [viewWillAppear]. Es posible que pueda hacerlo en el método del delegado de la vista web para cuando termine de cargarse la vista web. – lucius

6

Así que aquí está mi respuesta actualizada: he implementado una tabla usando una gran UIWebView para poner texto con estilo dentro de las celdas de la tabla en mi propia aplicación cliente de Twitter, HelTweetica (con fuente disponible). Funciona bastante bien siempre que comprenda cómo hacer el diseño en HTML y CSS.

Acaba de crear un NSMutableString y agrega las líneas de HTML que componen su documento. Puede hacer referencia a archivos externos, como archivos CSS, que se encuentran en la zona de pruebas de su aplicación. Puede establecer las acciones a medida URL como "youraction: //file.txt" que su Web delegado puede interceptar y procesar como un reemplazo IBAction s:

- (void) refreshWebView { 
    TwitterAccount *account = [twitter currentAccount]; 
    NSMutableString *html = [[NSMutableString alloc] init]; 
    // Open html and head tags 
    [html appendString:@"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"]; 
    [html appendString:@"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n"]; 
    [html appendString:@"<head>\n"]; 
    [html appendString:@"<meta name='viewport' content='width=device-width' />"]; 
    [html appendString:@"<link href='style-ipad.css' rel='styleSheet' type='text/css' />"]; 
    [html appendString:@"<script language='JavaScript' src='functions.js'></script>"]; 

    // Body 
    [html appendString:@"</head><body><div class='artboard'>"]; 

    // [...] 

    // Close artboard div, body. and html tags 
    [html appendString:@"</div></body></html>\n"]; 

    NSURL *baseURL = [NSURL fileURLWithPath: [[NSBundle mainBundle] bundlePath]]; 
    [self.webView loadHTMLString:html baseURL:baseURL]; 
    [html release]; 
} 

Y puede volver a cargar partes de la página mediante el uso de JavaScript :

- (void) refreshTabArea { 
    NSString *html = [self stringByEscapingQuotes: [self tabAreaHTML]]; 
    NSString *js = [NSString stringWithFormat: @"document.getElementById(\"tab_area\").innerHTML = \"%@\";", html]; 
    [self.webView stringByEvaluatingJavaScriptFromString:js]; 
} 
Cuestiones relacionadas