2011-10-29 8 views
7

Me gustaría hacer que mi aplicación de iPhone pueda cambiar entre máscaras (o temas de diseño, o apariencia, como madera, metal, color de la tierra, hombres, niñas, etc.).¿Cómo cambiar las máscaras (o temas de diseño) en la aplicación iOS?

Prepararé algunos conjuntos de máscaras que contengan imágenes para botones y fondos, sonidos y colores de texto, y dejaré que el usuario decida qué conjunto de máscara quiere usar según la configuración de la aplicación.

¿Cuál es la mejor práctica para implementar esto?

Las condiciones son:

  • Me gustaría utilizar el Interface Builder
  • necesito para apoyar iOS 3.1.3 y más tarde
  • Quiero hacer los conjuntos de pieles descargables desde internet (No puedo agrupar todas las carátulas de la aplicación, ya que un conjunto de carátulas requiere muchas imágenes y el tamaño del archivo de la aplicación podría aumentar si lo hago ... Tampoco quiero codificar ninguna información sobre carcasas específicas .)
  • Si una máscara personalizada no contiene uno o algunos elementos (como una imagen o r archivo de sonido), quiero que use el elemento faltante del conjunto predeterminado de máscara.
  • No quiero crear archivos Nib para cada aspecto. El archivo Nib para una pantalla debe ser el único en el paquete principal para facilitar el mantenimiento.

Estoy pensando en hacer una superclase de todos los UIViewControllers en mi aplicación y anular la parte que se cargue el archivo de plumilla, y en lugar de la carga desde el haz principal, la carga de los recursos de la piel que se guarda en el directorio del documento ... pero no sé cómo hacerlo ... El comportamiento predeterminado de los métodos de carga de plumillas siempre carga recursos del paquete principal y la información sobre los nombres de los archivos de recursos se pierde después de leer ...: (

Gracias de antemano por su ayuda.

+1

Hay una explicación muy completa sobre cómo desollar una aplicación iOS aquí: http://stackoverflow.com/questions/8919334/how-to-create-multiple-themes-skins-for-iphone-apps?rq= 1 También explica cómo pelar una punta, esp. de iOS 5. –

+1

Puede echar un vistazo a la siguiente biblioteca https://github.com/charithnidarsha/MultiThemeManager –

Respuesta

4

no estoy seguro acerca de las mejores prácticas .. Pero, si su aplicación no es lo suficientemente grande, entonces un plist bien estructurada es su amigo.

Inicialmente, podría elegir: Metal Theme. Lo siguiente debe contener:

Usted tiene un Singleton ThemeManager, o simplemente inserte un NSDictionary en uno de sus Singletons si corresponde.

El punto detrás de la ThemeManager es la correspondencia entre el activo y el tema ..

algunos ejemplos de código (escrito directamente en SOF .. No importa los errores de sintaxis):

#define kThemeMap(__x__) [[ThemeManager sharedManager] assetForCurrentTheme:__x__] 

... 

-(void)doUselessStuff { 
    UIImage* backgroundImage = [UIImage imageNamed:kThemeMap(@"FirstViewBG")]; 

    ... 

} 

//in the ThemeManager: 
//returns the appropriate name of the asset based on current theme 
-(NSString*)assetForCurrentTheme:(NSString*)asset { 
    //_currentTheme is an NSDictionary initialized from a plist. Plist can be downloaded, too. 
    NSString* newAsset = [_currentTheme objectForKey:asset]; 
    if(newAsset == nil) { 
     newAsset = [_defaultTheme objectForKey:asset]; 
    } 
    return asset; 
} 

//Let us assume the user selects Metal Theme somewhere .. Still coding ThemeManager: 
-(void)selectedNewTheme:(NSString*)newTheme { 
    //First, get the full path of the resource .. Either The main bundle, or documents directory or elsewhere.. 
    NSString* fullPath = ...; 
    self.currentTheme = [NSDictionary dictionaryWithContentsOfFile:fullPath]; 
} 

El plist archivos son sólo un diccionario con una cuerda a la cartografía de cadena ... algo como esto:

//Default.plist 
@"FirstViewBG" : @"FirstViewBG_Default.png" 
@"SecondViewBG" : @"SecondViewBG_Default.png" 
@"WinSound"  : @"WinSound_Default.aiff" 

//Metal.plist 
@"FirstViewBG" : @"FirstViewBG_Metal.png" 
@"SecondViewBG" : @"SecondViewBG_Metal.png" 
@"WinSound"  : @"WinSound_Metal.aiff" 

como alternativa, puede simplemente guardar el postfix, si eso es lo suficientemente bueno para yo u ... Pero, requerirá manipulación de cadenas, al cortar la extensión -> agregar el sufijo -> agregar la extensión ...

¿O tal vez hacer un prefijo?

+0

Muchas gracias por su respuesta y el código muy descriptivo! Esta podría ser una posible solución. :) – Taka

+0

La única razón por la que dudo en tomar este enfoque es que de esta manera tengo que mantener información redundante sobre el nombre del archivo de recursos tanto en el archivo Nib como en el Plist. Sin embargo, no costará mucho ... Todavía espero que haya una forma de leer los nombres de los archivos de recursos durante la carga del Nib, y agregar el sufijo o prefijo específico del tema al nombre del archivo en el proceso ... Cualquiera ¿idea? Si no es fácil o no es posible, tomaré este enfoque. Gracias. ;) – Taka

+0

aah .. Realmente no puedo pensar en una manera de hacerlo. Debe vincularlos como IBOutlets y personalizarlos en viewDidLoad;) – Mazyod

0

Puede categorizar en UIImage con el metodo imageNamed :, use el personalizado imageNamed: en lugar del predeterminado. En el método personalizado, selecciona la imagen por tema.

+0

Gracias por su respuesta. Bueno, funcionará, pero creo que no es una buena práctica usar Objective-C Category para anular un método. (Como se discutió en http://stackoverflow.com/questions/5272451/overriding-methods-using-categories-in-objective-c) En ese caso, podemos subclasificar UIImage para reemplazar imageNamed :, pero de esta manera no podemos usar Interface Constructor de manera efectiva. – Taka

Cuestiones relacionadas