Définir une sous-classe personnalisée de UINavigationBar dans UINavigationController par programmation
Personne ne sait comment je peux utiliser mon sous-classe personnalisée de UINavigationBar
si j'instancie UINavigationController
par programme (sans IB)?
Faites glisser un UINavigationController
de l'IB me montrer sous la Barre de Navigation et l'utilisation de l'Identité Inspectory je peux changer le type de classe et de définir mon propre sous-classe de UINavigationBar
mais par programmation, je ne peux pas, navigationBar
propriété de la manette de Navigation est en lecture seule...
Que dois-je faire pour personnaliser la barre de navigation par programmation? Est de l'IB en plus "puissant" que le "code"? J'ai cru tout ce qui peut être fait au bureau de l'IB peut être aussi fait par programmation.
- avez-vous eu de la chance de trouver une solution ailleurs?
- avez-vous obtenu aucune réponse à ce sujet?
Vous devez vous connecter pour publier un commentaire.
Vous n'avez pas besoin de coucher avec le XIB simplement utiliser KVC.
Depuis iOS5, apple fournit une méthode pour le faire directement. Référence
Comme de l'iOS 4, vous pouvez utiliser le
UINib
classe pour aider à résoudre ce problème.UINavigationBar
sous-classe.UINavigationController
uniqueobjet.
UINavigationController
'sUINavigationBar
à la sous-classe personnalisée.[navController setViewcontrollers[NSArray arrayWithObject:myRootVC]];
[navController pushViewController:myRootVC];
Dans le code:
Vous avez maintenant un
UINavigationController
avec votre customUINavigationBar
.Aussi loin que je peux dire, parfois il est en effet nécessaire à la sous-classe UINavigationBar, pour faire de la non standard restyling. Il est parfois possible d'éviter d'avoir à le faire en utilisant catégories, mais pas toujours.
Actuellement, autant que je sache, le seulement façon de personnaliser la UINavigationBar dans un UIViewController est par l'intermédiaire de l'IB (qui est, via une archive) - il ne devrait probablement pas être de cette façon, mais pour l'instant, il nous faut vivre avec elle.
C'est souvent très bien, mais parfois à l'aide de l'IB n'est pas vraiment possible.
Donc, j'ai vu trois options:
L'Option 1 était impossible (ou du moins trop ennuyeux), pour moi, dans ce cas, comme j'avais besoin de créer le UINavigationController par programme, 2 est un peu dangereux et de plus en plus une solution de dernier recours, à mon avis, j'ai donc choisi l'option 3.
Mon approche a été de créer un "modèle" de l'archive d'un UINavigationController, et désarchiver que, de retour dans
initWithRootViewController
.Voici comment:
De l'IB, j'ai créé un UINavigationController avec la classe définie pour le UINavigationBar.
Puis, j'ai pris le contrôleur existant, et enregistré une copie archivée de l'aide
+[NSKeyedArchiver archiveRootObject:toFile:]
. J'ai juste fait cette au sein de l'application délégué, dans le simulateur.J'ai ensuite utilisé le "xxd de" l'utilité avec l'option-i, pour générer du code c à partir de l'enregistrement du fichier, pour intégrer la version archivée dans mon sous-classe (
xxd -i path/to/file
).Dans
initWithRootViewController
je réactivation de ce modèle, et les mettre à la suite de la réactivation:Alors, je viens de prendre une nouvelle instance de mon UIViewController sous-classe qui a la barre de navigation personnalisée set:
Cela me donne un modal UITableViewController avec une barre de navigation et la barre d'outils tous ensemble, et avec la barre de navigation personnalisée classe en place. Je n'ai pas besoin de faire un peu méchant de la méthode de remplacement, et je n'ai pas à bricolons avec des plumes quand j'ai vraiment envie de travailler par programmation.
Je voudrais voir l'équivalent de
+layerClass
dans UINavigationController -+navigationBarClass
- mais pour l'instant, cela fonctionne.- Je utiliser "l'option 1"
Créer une plume fichier avec uniquement le UINavigationController en elle. Et de définir la UINavigationBar Classe de ma Classe personnalisée.
Michael solution fonctionne, mais vous pouvez éviter NSKeyedArchiver et " xxd l'utilité. Simplement sous-classe UINavigationController et remplacer
initWithRootViewController
, le chargement de votre personnalisé NavigationController PLUME directement:Mise à jour: à l'Aide de
object_SetClass()
ne fonctionne plus comme si iOS5 GM. Une solution alternative a été ajouté ci-dessous.Utilisation NSKeyedUnarchiver pour définir manuellement la réactivation de la classe pour la barre de navigation.
Remarque: Cette solution originale fonctionne uniquement pré-iOS5:
Il est une excellente solution, que j'ai posté ici -- injecter de la barre de navigation sous-classe directement dans votre vue de la
UINavigationController
:Un scénario, j'ai trouvé que nous avons besoin d'utiliser la sous-classe plutôt que la catégorie est de mettre en navigationbar backgroundcolor avec le modèle de l'image, parce que dans iOS5 écraser drawRect à l'aide de catégorie ne fonctionne plus. Si vous voulez soutenir ios3.1-5.0, la seule façon vous pouvez faire est de la sous-classe navigationbar.
Ces catégories de méthodes sont dangereux et n'est pas pour les novices. Aussi la complication avec iOS4 et iOS5 être différent, en fait une zone qui peut causer des bugs pour de nombreuses personnes. Voici un simple sous-classe que j'utilise qui prend en charge la version iOS4.0 ~ iOS6.0 et est très simple.
.h
.m
C'est pas recommandé à la sous-classe le
UINavigationBar
classe. La meilleure façon de personnalisation de la barre de navigation consiste à définir les propriétés pour le faire apparaître comme vous le souhaitez et d'utiliser des points de vue à l'intérieur de UIBarButtonItems avec un délégué pour obtenir le comportement souhaité.Ce que vous essayez de faire que les besoins de sous-classement?
Aussi, je ne pense pas que IB est en fait le remplacement de la barre de navigation. Je suis sûr que c'est tout simplement pas l'affichage par défaut et a votre barre de navigation personnalisée comme une sous-vue. Si vous appelez UINavigationController.navigationBar, pensez-vous obtenir une instance de votre bar?
Si vous voulez à la sous-classe navBar juste pour changer l'image de fond - il n'est pas nécessaire d'en iOS 5.
Il y aura de la méthode comme celui-ci setBackgroundImage
setBackgroundImage:forBarMetrics:
comme décrit ici:developer.apple.com/library/IOS/#documentation/UIKit/Reference/...Plus de obb64 commentaire, j'ai fini par utiliser son truc avec
setViewControllers:animated:
régler le contrôleur comme l'rootController
pour lanavigationController
chargé de la plume. Voici le code que j'utilise: