La sous-vue UINavigationBar cache le bon UIBarButtonItem
-
06-07-2019 - |
Question
Dans le contrôleur de vue de table racine, j'ajoute une sous-vue contenant une image:
[self.navigationController.navigationBar addSubview:imageView];
Puis, dans un contrôleur de vue de table enfant que je pousse sur la pile, je définis un UIBarButtonItem de droite:
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithTitle:@"Right" style:UIBarButtonItemStylePlain target:self action:@selector(rightAction:)];
self.navigationItem.rightBarButtonItem = rightButton;
[rightButton release];
Je ne comprends pas pourquoi le bouton ne s'affiche pas dans la barre de navigation. Si j'appuie sur (l'espace vide), la méthode rightAction: est invoquée de sorte que le bouton "est". attendez-vous qu’il ne soit pas affiché.
J'ai essayé d'envoyer la sous-vue imageView à l'arrière de la barre de navigation, mais en vain. Cela a du sens, puisque le bouton appartient en fait à UINavigationItem de toute façon ...
Est-ce que quelqu'un sait comment je peux afficher ce bouton correctement?
Mise à jour: le bouton Précédent s'affiche correctement, mais il est ajouté par le système si ...
La solution
Une meilleure méthode pour ajouter une image à un UINavigationBar
consiste à la sous-classer ou à en créer une catégorie et à remplacer la méthode drawRect
:
// #Lighter r,g,b,a #Darker r,g,b,a
#define MAIN_COLOR_COMPONENTS { 0.153, 0.306, 0.553, 1.0, 0.122, 0.247, 0.482, 1.0 }
#define LIGHT_COLOR_COMPONENTS { 0.478, 0.573, 0.725, 1.0, 0.216, 0.357, 0.584, 1.0 }
@implementation UINavigationBar (UINavigationBarCategory)
- (void)drawRect:(CGRect)rect {
if (imageReady) {
UIImage *img = [UIImage imageNamed: @"navigation_background.png"];
[img drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
} else {
// Render yourself instead.
// You will need to adjust the MAIN_COLOR_COMPONENTS and LIGHT_COLOR_COMPONENTS to match your app
// emulate the tint colored bar
CGContextRef context = UIGraphicsGetCurrentContext();
CGFloat locations[2] = { 0.0, 1.0 };
CGColorSpaceRef myColorspace = CGColorSpaceCreateDeviceRGB();
CGFloat topComponents[8] = LIGHT_COLOR_COMPONENTS;
CGGradientRef topGradient = CGGradientCreateWithColorComponents(myColorspace, topComponents, locations, 2);
CGContextDrawLinearGradient(context, topGradient, CGPointMake(0, 0), CGPointMake(0,self.frame.size.height/2), 0);
CGGradientRelease(topGradient);
CGFloat botComponents[8] = MAIN_COLOR_COMPONENTS;
CGGradientRef botGradient = CGGradientCreateWithColorComponents(myColorspace, botComponents, locations, 2);
CGContextDrawLinearGradient(context, botGradient,
CGPointMake(0,self.frame.size.height/2), CGPointMake(0, self.frame.size.height), 0);
CGGradientRelease(botGradient);
CGColorSpaceRelease(myColorspace);
// top Line
CGContextSetRGBStrokeColor(context, 1, 1, 1, 1.0);
CGContextMoveToPoint(context, 0, 0);
CGContextAddLineToPoint(context, self.frame.size.width, 0);
CGContextStrokePath(context);
// bottom line
CGContextSetRGBStrokeColor(context, 0, 0, 0, 1.0);
CGContextMoveToPoint(context, 0, self.frame.size.height);
CGContextAddLineToPoint(context, self.frame.size.width, self.frame.size.height);
CGContextStrokePath(context);
}
}
@end
Si vous le faites de cette manière, vos boutons s'afficheront correctement et seront moins "hacky".
Autres conseils
Je pense que vous devez définir la vue du titre de l'élément de navigation sur votre imageView.
self.navigationItem.titleView = imageView;
Je suppose que le UINavigationBar
affiche le UINavigationItem
dans une sous-vue et que vous ajoutiez votre UIImageView
au-dessus de cette sous-vue.
Dans l'une de mes vues, une étiquette et une image sont affichées. Je pense avoir ajouté l'étiquette et la vue d'image à une vue que j'ai ensuite utilisée pour le titreView.