2012-01-19 15 views
52

Ho un'app per iPhone pronta e approvata dall'app store. Ora voglio creare diversi temi per la mia app. Qualcuno può aiutarmi, con informazioni/link/passaggi su come creare temi per la mia app?Come creare più temi/skin per le app per iphone?

Voglio creare un tema di metallo per i ragazzi e un tema rosa per le ragazze. Sempre per tema intendo, l'intera app (caratteristiche e funzionalità) rimarrà la stessa, ma a seconda di chi è l'utente (ragazzo o ragazza), lui/lei può scegliere il tema che desidera vedere. E quando il tema cambia, solo le immagini/Background/musica cambieranno in base al tema applicato.

Grazie mille!

+0

Cosa intendi esattamente per temi? Cosa vuoi "tema"? –

+3

Sono abbastanza sicuro che intendesse temi come i temi di Windows! – Ravi

+47

Questa domanda non avrebbe dovuto essere chiusa, è una domanda perfettamente legittima con un'interessante serie di possibili soluzioni tecniche e la maggior parte delle persone comprende il significato di "tema" nel contesto di un'app. –

risposta

122

Questo è abbastanza difficile in quanto le app non hanno l'equivalente di un foglio di stile CSS.

Per prima cosa è necessario capire quali parti dell'applicazione si desidera applicare e quando si desidera consentire all'utente di scambiare le pelli.

Suppongo che vogliate cambiare le immagini e i colori dei caratteri, e che va bene se l'utente deve riavviare l'app per cambiare la skin (ciò renderà le cose più semplici per ora).

Crea un plist contenente tutte le immagini e i colori della tua immagine. Il plist sarà un dizionario con nomi di chiavi neutrali di tema sensibile per le immagini e i colori (ad esempio, non avere un colore chiamato "rosso", chiamarlo "primaryHeadingColor"). Le immagini saranno nomi di file e i colori possono essere stringhe esadecimali, ad es. FF0000 per il rosso.

Avrai un plist per ogni tema.

Creare una nuova classe denominata ThemeManager e renderlo un Singleton aggiungendo il seguente metodo:

+ (ThemeManager *)sharedManager 
{ 
    static ThemeManager *sharedManager = nil; 
    if (sharedManager == nil) 
    { 
     sharedManager = [[ThemeManager alloc] init]; 
    } 
    return sharedManager; 
} 

La classe ThemeManager avrà una proprietà NSDictionary denominata "stili", e nel metodo init si caricare il tema nei vostri stili dictionary come questo:

- (id)init 
{ 
    if ((self = [super init])) 
    { 
     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
     NSString *themeName = [defaults objectForKey:@"theme"] ?: @"default"; 

     NSString *path = [[NSBundle mainBundle] pathForResource:themeName ofType:@"plist"]; 
     self.styles = [NSDictionary dictionaryWithContentsOfFile:path]; 
    } 
    return self; 
} 

(Nota: alcune persone non piace fare un sacco di lavoro all'interno di un metodo init non ho mai trovato ad essere un problema, ma se si preferisce,. creare un metodo separato per caricare il dizionario dei temi e ca lo proviene dal codice di installazione della tua app).

Nota come ottengo il nome per il tema plist dai valori predefiniti dell'utente. Ciò significa che l'utente può selezionare un tema nelle tue preferenze e salvarlo e l'app caricherà quel tema la prossima volta che verrà lanciato. Ho inserito un nome di tema predefinito di "default" se nessun tema è selezionato, quindi assicurati di avere un file di tema default.plist (o modifica il parametro "predefinito" nel codice a qualsiasi cosa venga effettivamente chiamata la tua plist di temi predefinita).

Ora che hai caricato il tema devi usarlo; Suppongo che la tua app abbia varie immagini e etichette di testo. Se stai caricando e disponendo quelli in codice allora questa parte è facile. Se lo fai nei pennini, è un po 'più complicato, ma ti spiegherò come gestirlo più tardi.

Ora normalmente si dovrebbe caricare un'immagine dicendo:

UIImage *image = [UIImage imageNamed:@"myImage.png"]; 

Ma se si vuole che l'immagine sia themable, sarà ora necessario caricarlo dicendo

NSDictionary *styles = [ThemeManager sharedManager].styles; 
NSString *imageName = [styles objectForKey:@"myImageKey"]; 
UIImage *image = [UIImage imageNamed:imageName]; 

che verrà cerca nel file del tema l'immagine tematica che corrisponde alla chiave "myImageKey" e la caricherà. A seconda del file di tema che hai caricato otterrai uno stile diverso.

Utilizzerai queste tre righe molto in modo da poterli avvolgere in una funzione. Una grande idea sarebbe quella di creare una categoria sulla UIImage che dichiara un metodo chiamato qualcosa come:

+ (UIImage *)themeImageNamed:(NSString *)key; 

Poi per usarlo si può solo sostituire le chiamate a [UIImage imageNamed: @ "foo.png"]; con [UIImage themeImageNamed: @ "foo"]; dove foo è ora la chiave del tema al posto del nome effettivo dell'immagine.

Ok, questo è tutto per le tue immagini. Per tema i colori delle etichette, si supponga che si sta impostando i colori delle etichette dicendo:

someLabel.color = [UIColor redColor]; 

Si potrebbe ora sostituire quella con:

NSDictionary *styles = [ThemeManager sharedManager].styles; 
NSString *labelColor = [styles objectForKey:@"myLabelColor"]; 
someLabel.color = [UIColor colorWithHexString:labelColor]; 

Ora avrete notato che UIColor non ha un metodo "colorWithHexString:" - dovrai aggiungerlo usando una categoria. Puoi Google per le soluzioni "UIColor con stringa esadecimale" per trovare il codice per farlo, o ho scritto una categoria utile che lo fa e un po 'di più qui: https://github.com/nicklockwood/ColorUtils

Se hai prestato attenzione, anche pensare che invece di scrivere quelle tre righe più e più volte, perché non aggiungere un metodo per UIColor chiamato:

+ (UIColor *)themeColorNamed:(NSString *)key; 

Proprio come abbiamo fatto con UIImage? Grande idea!

Quindi è tutto. Ora puoi modificare qualsiasi immagine o etichetta nella tua app. È possibile utilizzare lo stesso trucco per impostare il nome del font o un numero qualsiasi di altre proprietà visive potenzialmente utilizzabili.

C'è solo una piccola cosa che abbiamo dimenticato ...

Se hai costruito la maggior parte dei vostri punti di vista come pennini (e non vedo alcun motivo per cui non sarebbe), allora queste tecniche non sono in corso lavorare perché i nomi delle immagini e i colori dei caratteri sono sepolti all'interno di dati di pennini impenetrabili e non vengono impostati nel codice sorgente.

ci sono alcuni approcci per risolvere questo:

1) Si potrebbe fare copie a tema duplicato del pennini e poi mettere i nomi pennino nel plist tema e caricarli dal vostro gestore di temi. Quello non è troppo male, solo implementare il metodo nibName dei controller di vista in questo modo:

- (NSString *)nibName 
{ 
    NSDictionary *styles = [ThemeManager sharedManager].styles; 
    return [styles objectForKey:NSStringFromClass([self class])]; 
} 

Avviso mio trucchetto di utilizzare il nome della classe del controller della vista come la chiave - che vi farà risparmiare un po 'di battitura a macchina perché si può basta creare un ThemeViewController di base con questo metodo e ereditare da esso tutti i controller di visualizzazione utilizzabili.

Questo approccio implica comunque il mantenimento di più copie di ciascun pennino, che è un incubo di manutenzione se è necessario modificare qualsiasi schermata in un secondo momento.

2) È possibile creare IBOutlet per tutte le immagini e le etichette nei pennini, quindi impostare le loro immagini e colori nel codice nel metodo viewDidLoad. Questo è probabilmente l'approccio più ingombrante, ma almeno non si dispone di punti duplicati da mantenere (questo è essenzialmente lo stesso problema della localizzazione dei pennini btw, e più o meno le stesse opzioni di soluzione).

3) È possibile creare una sottoclasse personalizzata di UILabel denominata ThemeLabel che imposta automaticamente il colore del carattere utilizzando il codice sopra quando viene creata un'istanza dell'etichetta, quindi utilizzare tali ThemeLabels nei propri file invece di UILabels regolari impostando la classe del etichetta per ThemeLabel in Interface Builder. Sfortunatamente se hai più di un font o colore di font, dovrai creare una sottoclasse UILabel diversa per ogni stile differente.

Oppure potresti essere subdolo e usare qualcosa come il tag view o la proprietà accessibilityLabel come chiave del dizionario di stile in modo da poter avere una singola classe ThemeLabel e impostare l'etichetta accessibilità in Interface Builder per selezionare lo stile.

Lo stesso trucco potrebbe funzionare per ImageViews: creare una sottoclasse UIImageView denominata ThemeImageView che, nel metodo awakeFromNib sostituisce l'immagine con un'immagine a tema basata sul tag o sulla proprietà accessibilityLabel.

Personalmente mi piace l'opzione 3 migliore perché risparmia sulla codifica. Un altro vantaggio dell'opzione 3 è che se si desidera poter scambiare temi in fase di esecuzione, è possibile implementare un meccanismo in cui il gestore temi ricarica il dizionario del tema, quindi trasmette una NSNotification a tutti i temi ThemeLabels e ThemeImageViews che indicano loro di ridisegnarsi. Ciò richiederebbe probabilmente solo 15 righe di codice in più.

In ogni caso, è disponibile una soluzione tematica completa per iOS. Prego!

UPDATE:

Come di iOS 5, è ora possibile impostare attributi personalizzati dal percorso chiave in Interface Builder, il che significa che non è più necessario creare una sottoclasse vista per ogni proprietà themable, o maltrattare il tag o accessibilityLabel per selezionare gli stili. È sufficiente fornire alla sottoclasse UILabel o UIImageView una proprietà stringa per indicare quale chiave tema deve essere utilizzata dal plist e quindi impostare tale valore in IB.

UPDATE 2:

Come di iOS 6, v'è ora un sistema di skinning limitata integrato in iOS che consente di utilizzare una proprietà chiamata proxy UIAppearance per la pelle tutte le istanze di una determinata classe di controllo in una sola volta (c'è un buon tutorial sulle API di UIAppearance here). Vale la pena controllare se questo è sufficiente per le esigenze di skinning, ma in caso contrario, la soluzione che ho delineato sopra funziona ancora bene e può essere utilizzata al posto o in combinazione con UIAppearance.

+3

È davvero fantastico grazie nik – sinh99

+4

Oh mio Dio! Penso che questa sia la migliore, migliore, migliore guida/risposta/guida/tutorial che abbia mai letto. Non sei ancora arrivato alla fine, ma continua a stupirti di come hai speso tempo per spiegare le cose in modo così semplice. Veramente stupefacente! Vorrei che anche le persone nei canali IRC fossero così gentili. Molte grazie. – Neeku

+1

Nice, grazie +1 – TonyMkenu

Problemi correlati