2010-03-29 9 views
9

Digamos que estoy desarrollando una aplicación para iPhone que es un catálogo de automóviles. El usuario elegirá un automóvil de una lista, y le presentaré una vista detallada del automóvil, que describirá cosas como la velocidad máxima. La vista detallada será esencialmente una UIWebView que está cargando un archivo HTML existente.Cambiando CSS sobre la marcha en un UIWebView en iPhone

Diferentes usuarios vivirán en diferentes partes del mundo, por lo que les gustará ver la velocidad máxima para el automóvil en las unidades que sean apropiadas para su localidad. Digamos que hay dos de esas unidades: SI (km/h) y convencional (mph). Supongamos también que el usuario podrá cambiar las unidades de visualización presionando un botón en la pantalla; cuando eso sucede, la pantalla de detalles debe cambiar para mostrar las unidades relevantes.

Hasta ahora, esto es lo que hice para intentar solucionar esto.

El HTML podría ser algo como esto:

 
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US"> 
<head> 
<title>Some Car</title> 
<link rel="stylesheet" media="screen" type="text/css" href="persistent.css" /> 
<link rel="alternate stylesheet" media="screen" type="text/css" href="si.css" title="si" /> 
<link rel="alternate stylesheet" media="screen" type="text/css" href="conventional.css" title="conventional" /> 
<script type="text/javascript" src="switch.js"></script> 
</head> 
<body> 
<h1>Some Car</h1> 
<div id="si"> 
<h2>Top Speed: 160 km/h</h2> 
</div> 
<div id="conventional"> 
<h2>Top Speed: 100 mph</h2> 
</div> 
</body> 

La hoja de estilo alrededor del stent, persistent.css:

#si 
{ 
    display:none; 
} 

#conventional 
{ 
    display:none; 
} 

La primera hoja de estilo alternativo, si.css:

#si 
{ 
    display:inline; 
} 

#conventional 
{ 
    display:none; 
} 

Y la segunda hoja de estilo alternativa, conventional.css:

#si 
{ 
    display:none; 
} 

#conventional 
{ 
    display:inline; 
} 

Basado en un tutorial en A List Apart, mis switch.js se ve algo como esto:

function disableStyleSheet(title) 
{ 
    var i, a; 
    for (i = 0; (a = document.getElementsByTagName("link")[i]); i++) 
    { 
     if ((a.getAttribute("rel").indexOf("alt") != -1) && (a.getAttribute("title") == title)) 
     { 
      a.disabled = true; 
     } 
    } 
} 

function enableStyleSheet(title) 
{ 
    var i, a; 
    for (i = 0; (a = document.getElementsByTagName("link")[i]); i++) 
    { 
     if ((a.getAttribute("rel").indexOf("alt") != -1) && (a.getAttribute("title") == title)) 
     { 
      a.disabled = false; 
     } 
    } 
} 

function switchToSiStyleSheet() 
{ 
    disableStyleSheet("conventional"); 
    enableStyleSheet("si"); 
} 

function switchToConventionalStyleSheet() 
{ 
    disableStyleSheet("si"); 
    enableStyleSheet("conventional"); 
} 

Mi manejador de acción del botón se ve algo como esto:

- (void)notesButtonAction:(id)sender 
{ 
    static BOOL isUsingSi = YES; 
    if (isUsingSi) 
    { 
     NSString* command = [[NSString alloc] initWithString:@"switchToSiStyleSheet();"]; 
     [self.webView stringByEvaluatingJavaScriptFromString:command]; 
     [command release]; 
    } 
    else 
    { 
     NSString* command = [[NSString alloc] initWithFormat:@"switchToConventionalStyleSheet();"]; 
     [self.webView stringByEvaluatingJavaScriptFromString:command]; 
     [command release]; 
    } 
    isUsingSi = !isUsingSi; 
} 

es el Aquí primer problema La primera vez que se pulsa el botón, el UIWebView no cambia. La segunda vez que se golpea, parece que la hoja de estilo convencional está cargada. La tercera vez, cambia a la hoja de estilo SI; la cuarta vez, volver a lo convencional, y así sucesivamente. Entonces, básicamente, solo esa primera pulsación de botón no parece hacer nada.

Aquí está el segundo problema. No estoy seguro de cómo cambiar a la hoja de estilo correcta en la carga inicial del UIWebView. He intentado esto:

- (void)webViewDidFinishLoad:(UIWebView *)webView 
{ 
    NSString* command = [[NSString alloc] initWithString:@"switchToSiStyleSheet();"]; 
    [self.webView stringByEvaluatingJavaScriptFromString:command]; 
    [command release]; 
} 

Pero, al igual que el primer botón de golpe, no parece hacer nada.

¿Alguien puede ayudarme con estos dos problemas?

+0

Irrelevante, pero puede simplemente las 3 instrucciones ObjC en una: '[self.webView stringByEvaluatingJavaScriptFromString: @ "switchToSiStyleSheet();"]; ' – kennytm

Respuesta

2

Probablemente ya hace tiempo que se dio cuenta de esto, pero ya que esta es la mejor página sobre este tema en la web, responderé para completar.

Estabas muy cerca. Todo lo que necesita hacer es agregar una llamada inicial a su función en su cabecera de HTML.

<head> 
<title>Some Car</title> 
<link rel="stylesheet" media="screen" type="text/css" href="persistent.css" /> 
<link rel="alternate stylesheet" media="screen" type="text/css" href="si.css" title="si" /> 
<link rel="alternate stylesheet" media="screen" type="text/css" href="conventional.css" title="conventional" /> 
<script type="text/javascript" src="switch.js"></script> 
<script type="text/javascript">switchToSiStyleSheet();</script> 
</head> 
Cuestiones relacionadas