UINavigationBar: l'apparence fonctionne mais pas UINavigationBar: appearanceWhenContained in

J'ai besoin de placer la barre de navigation à une couleur faite sur command et ce code suivant fera ceci:

[[UINavigationBar appearance] setBackgroundImage:navigationBarTileImage forBarMesortingcs:UIBarMesortingcsDefault]; 

Cependant, mon application appelle le système MFMailComposeViewController et MFMessageComposeViewController et je veux que la barre de navigation soit la couleur par défaut pour ces vues, donc je l'ai fait:

 [[UINavigationBar appearanceWhenContainedIn: [MyViewControllerBase class], [MyViewController1 class], [MyViewController2 class], nil] setBackgroundImage:navigationBarTileImage forBarMesortingcs:UIBarMesortingcsDefault]; 

Cependant maintenant la barre de navigation n'a plus ma couleur par défaut. Pourquoi appearanceWhenContainedIn ne fonctionne pas?

L'argument de appearanceWhenContainedIn: représente une hiérarchie de confinement vue (et / ou vue), pas une list de conteneurs possibles. (Certes, les documents ne sont pas clairs à ce sujet Voir la video de WWDC 2011. ) Ainsi,

 [UINavigationBar appearanceWhenContainedIn:[NSArray arrayWithObjects:[MyViewControllerBase class], [MyViewController1 class], [MyViewController2 class], nil]] 

vous donne un proxy d'apparence pour un UINavigationBar contenu dans un MyViewControllerBase , qui est à son tour dans un MyViewController1 dans un MyViewController2 . Je suppose que ce n'est pas la hiérarchie de confinement que vous avez.

Au lieu de cela, regardez le controller de vue qui contient votre barre de navigation. C'est probablement un UINavigationController générique … mais vous ne pouvez pas le faire

 [UINavigationBar apperanceWhenContainedIn:[NSArray arrayWithObject:[UINavigationController class]]] 

parce que vous aurez aussi les controllers de courrier / message. Et malheureusement, alors que vous pouvez get le proxy d'apparence pour un UINavigationBar dans un controller de courrier / message, il n'y a pas moyen de lui dire d'annuler les changements d'apparence effectués à un niveau plus générique.

Il semble que la solution habituelle à de tels scénarios consiste à créer soi-même une sous-class UINavigationController et à l'utiliser pour les parties de l'interface user que vous voulez habiller. La sous-class peut être vide – elle n'existe que pour identifier les parties de votre interface user pour appearanceWhenContainedIn: :. (Pendant ce time, des choses comme MFMailComposeViewController continuent d'utiliser l'apparence par défaut car elles utilisent toujours le générique UINavigationController .)

En effet, comme le dit @rickster, la méthode appearanceWhenContainedIn: personnalise les apparences pour les instances d'une class contenue dans une instance d'une class de conteneur, ou des instances dans une hiérarchie.

Dans tous les cas, vous ne disposez pas d'un set de classs contenues que vous souhaitez personnaliser, mais de conteneurs différents. La solution pour pouvoir personnaliser plusieurs composants consiste simplement à créer un tableau des classs que vous devez personnaliser et à parcourir! Ainsi:

 NSArray *navigationClass = [NSArray arrayWithObjects:[BSNavigationController class], [DZFormNavigationController class], nil]; for (Class class in navigationClass) { //// Customize all the UINavigationBar background image tilling [[UINavigationBar appearanceWhenContainedIn:class, nil] setBackgroundImage:[UIImage imageNamed:@"yourImage"] forBarMesortingcs:UIBarMesortingcsDefault]; [[UINavigationBar appearanceWhenContainedIn:class, nil] setTintColor:[UIColor blackColor]]; // Title Text Atsortingbutes NSDictionary *titleAtsortingbutes = [NSDictionary dictionaryWithObjectsAndKeys: [UIColor whiteColor], UITextAtsortingbuteTextColor, [UIColor darkGrayColor], UITextAtsortingbuteTextShadowColor, [UIFont boldSystemFontOfSize:20.0], UITextAtsortingbuteFont, [NSValue valueWithUIOffset:UIOffsetMake(0, 1)], UITextAtsortingbuteTextShadowOffset,nil]; //// Customize all the UINavigationBar title atsortingbutes [[UINavigationBar appearanceWhenContainedIn:class, nil] setTitleTextAtsortingbutes:titleAtsortingbutes]; }