Est-ce possible?
Je souhaite modifier la valeur alpha de la barre de navigation dans mon contrôleur de vue (dans une animation), mais si je le fais, self.navigationController.navigationBar.alpha = 0.0;
, la partie de l'écran prise par la barre de navigation disparaît totalement et laisse une zone noire, ce qui n'est pas ce que j'ai '. J'aimerai (je préférerais que ce soit la couleur de l'arrière-plan de self.view
).
Tout en appuyant la réponse de Colin, je souhaite vous donner un conseil supplémentaire pour personnaliser l’apparence d’un UINavigationBar, y compris l’alpha.
L'astuce consiste à utiliser UIAppearance pour votre NavigationBar. Cela vous permet d’affecter un UIImage au backgroundImage de votre NavigationBar. Vous pouvez générer ces UIImages par programme et utiliser pour cela UIColors et définir les propriétés alpha des couleurs _ comme vous le souhaitez. Je l'ai fait dans l'une de mes propres applications et cela fonctionne comme prévu.
Ici, je vous donne quelques extraits de code:
Par exemple. dans votre ..AppDelegate.m, ajoutez ces lignes dans didFinishLaunchingWithOptions:
//create background images for the navigation bar
UIImage *gradientImage44 = nil; //replace "nil" with your method to programmatically create a UIImage object with transparent colors for portrait orientation
UIImage *gradientImage32 = nil; //replace "nil" with your method to programmatically create a UIImage object with transparent colors for landscape orientation
//customize the appearance of UINavigationBar
[[UINavigationBar appearance] setBackgroundImage:gradientImage44 forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBackgroundImage:gradientImage32 forBarMetrics:UIBarMetricsLandscapePhone];
[[UINavigationBar appearance] setBarStyle:UIBarStyleDefault];
Implémentez des méthodes pratiques pour créer par programme des objets UIImage, par exemple. créer une nouvelle catégorie pour UIImage:
//UIImage+initWithColor.h
//
#import <UIKit/UIKit.h>
@interface UIImage (initWithColor)
//programmatically create an UIImage with 1 pixel of a given color
+ (UIImage *)imageWithColor:(UIColor *)color;
//implement additional methods here to create images with gradients etc.
//[..]
@end
//UIImage+initWithColor.m
//
#import "UIImage+initWithColor.h"
#import <QuartzCore/QuartzCore.h>
@implementation UIImage (initWithColor)
+ (UIImage *)imageWithColor:(UIColor *)color
{
CGRect rect = CGRectMake(0, 0, 1, 1);
// create a 1 by 1 pixel context
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
[color setFill];
UIRectFill(rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
Retravaillez la création de votre image dans 1. (#import "UIImage + initWithColor.h" dans AppDelegate.m et remplacez le "nil"):
_ {C'est votre centre d'intérêt: en modifiant la propriété alpha de vos couleurs, vous influencez également le niveau d'opacité de votre NavigationBar!} _
UIImage *gradientImage44 = [UIImage imageWithColor:[UIColor colorWithRed:1.0 green:0.0 blue:1.0 alpha:0.2]];
UIImage *gradientImage32 = [UIImage imageWithColor:[UIColor colorWithRed:1.0 green:0.0 blue:1.0 alpha:0.2]];
J'ai créé un petit {projet de démonstration} _ et je vous ai ajouté deux captures d'écran: La vue elle-même a une couleur d'arrière-plan jaune. .La copie d'écran 1 montre une barre de navigation avec une valeur pour alpha = 0,2 . La capture d'écran 2 montre une barre de navigation avec une valeur pour alpha = 0,8.
La façon la plus simple de procéder consiste à modifier le composant alpha de la vue d'arrière-plan de navigationBar, qui à ce moment-là (iOS9) est une première sous-vue navigationBar. Notez cependant que nous ne savons jamais si la hiérarchie des sous-vues sera modifiée par Apple dans les versions ultérieures, alors soyez prudent.
let navigationBackgroundView = self.navigationController?.navigationBar.subviews.first
navigationBackgroundView?.alpha = 0.7
Directement à partir de la référence développeur Apple:
"La barre de navigation ne contient que quelques personnalisations directes. Plus précisément, il est correct de modifier les propriétés
barStyle
,tintColor
ettranslucent
, mais vous ne devez jamais directement changerUIView
- les propriétés de niveau telles que les propriétésframe
,bounds
,alpha
ouhidden
directement. "
Vous pouvez toutefois définir la propriété de translucidité de la barre de navigation. Si vous le faites, [self.navigationController.navigationBar setTranslucent:YES];
.__ devrait résoudre votre problème. Vous pouvez également essayer de voir si vous souhaitez utiliser l’un des énumérations UIBarStyle
.
La réponse de MickBraun dans Swift:
Dans AppDelegate.Swift, ajoutez ces lignes dans didFinishLaunchingWithOptions:
// create background images for the navigation bar
let gradientImage44 = UIImage.imageWithColor(UIColor(red: 1.0, green: 0.0, blue: 1.0, alpha: 0.2))
let gradientImage32 = UIImage.imageWithColor(UIColor(red: 1.0, green: 0.0, blue: 1.0, alpha: 0.2))
// customize the appearance of UINavigationBar
UINavigationBar.appearance().setBackgroundImage(gradientImage44, forBarMetrics: .Default)
UINavigationBar.appearance().setBackgroundImage(gradientImage32, forBarMetrics: .Compact)
UINavigationBar.appearance().barStyle = .Default
Implémentez des méthodes pratiques pour créer par programme des objets UIImage.
class func imageWithColor(colour: UIColor) -> UIImage {
let rect = CGRectMake(0, 0, 1, 1)
// Create a 1 by 1 pixel content
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
colour.setFill()
UIRectFill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
Vous avez quelques options en fonction, en partie, du style de barre de votre UINavigationBar
. L'essentiel est de réaliser que vous n'êtes probablement pas obligé d'animer la propriété alpha pour obtenir l'effet que vous décrivez.
UIBarStyleDefault
ou UIBarStyleBlackOpaque
L'option A consiste à définir votre propriété UINavigationBar translucent sur YES, puis à animer l'alpha:
navigationBar.translucent = YES; // ideally set this early, in the nib/storyboard, or viewDidLoad
...
[UIView animateWithDuration: 1.0
animations: ^{
// toggle:
navigationBar.alpha = navigationBar.alpha == 0 ? 1.0 : 0.0;
}];
Dans ce scénario, votre vue sera positionnée derrière votre barre de navigation, même si son alpha est 1.0. L'inconvénient de ce scénario est que même avec un alpha 1.0, vous pouvez voir une teinte de la couleur d'arrière-plan de votre vue derrière le UINavigationBar. En outre, toutes vos sous-vues devront être positionnées à 44 points du haut.
UIBarStyleDefault
ou UIBarStyleBlackOpaque
Option B consiste à masquer la barre de navigation dans une animation de transition à résolution croisée. Cela exposera le superview de UINavigationBar
. Si vous utilisez un UINavigationController
, le fond noir de la vue UINavigationController
correspond à ce que vous verrez - mais vous pouvez définir la couleur d'arrière-plan de la vue UINavigationController
pour qu'elle corresponde à la vue et obtenir l'effet souhaité:
UINavigationBar* navigationBar = self.navigationController.navigationBar;
self.navigationController.view.backgroundColor = self.view.backgroundColor;
[UIView transitionWithView: navigationBar
duration: 1.0
options: UIViewAnimationOptionTransitionCrossDissolve
animations: ^{
// toggle:
navigationBar.hidden = !navigationBar.hidden;
}
completion: nil];
Une chose à surveiller avec cette solution peut être un problème de mise en page si UINavigationController
met à jour votre cadre de vue car vous avez masqué UINavigationBar
. Ce serait très bien, sauf que vos sous-vues pourraient augmenter de 44 pixels si elles sont ancrées en haut à gauche. Pour contourner ce problème, vous pouvez envisager d'ancrer vos sous-vues au bas de votre vue (avec des ressorts ou des contraintes de présentation).
UIBarStyleDefault
ou UIBarStyleBlackOpaque
L'option C consiste à masquer le UINavigationBar
avec une autre vue, en utilisant à nouveau une animation de transition à résolution croisée:
UINavigationBar* navigationBar = self.navigationController.navigationBar;
[UIView transitionWithView: navigationBar
duration: 1.0
options: UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionAllowAnimatedContent
animations: ^{
// toggle:
const int tag = 1111;
UIView* navOverlayView = [navigationBar viewWithTag: tag];
if ( navOverlayView == nil )
{
navOverlayView = [[UIView alloc] initWithFrame: CGRectInset( navigationBar.bounds, 0, -3 ) ];
navOverlayView.backgroundColor = self.view.backgroundColor;
navOverlayView.tag = tag;
[navigationBar addSubview: navOverlayView];
}
else
{
[navOverlayView removeFromSuperview];
}
}
completion: nil];
UIBarStyleBlackTranslucent : Cette option est la plus simple, car UINavigationBar
est déjà translucide et votre vue est déjà masquée. Animez simplement l'alpha:
[UIView animateWithDuration: 1.0
animations: ^{
// toggle:
navigationBar.alpha = navigationBar.alpha == 0 ? 1.0 : 0.0;
}];
Si vous voulez juste vous débarrasser de la navigationBar
de façon animée, vous pouvez le faire:
[self.navigationController setNavigationBarHidden:YES animated:YES];
Si vous souhaitez contrôler l'animation et qu'il est nécessaire de définir alpha
sur 0.0
, lisez la suite:
La "boîte noire" que vous voyez provient de la vue ou de la fenêtre sous-jacente. Si vous voulez juste que vos vues colorent au lieu de la "boîte noire", faites:
self.navigationController.view.backgroundColor = self.view.backgroundColor;
[UIView animateWithDuration:1.0 delay:1.0 options:0 animations:^{
self.navigationController.navigationBar.alpha = 0.0;
} completion:NULL];
Si vous voulez que votre vue réelle soit là où se trouvait la navigationBar
, vous devez augmenter la height
de votre vue:
[UIView animateWithDuration:1.0 delay:1.0 options:0 animations:^{
self.navigationController.navigationBar.alpha = 0.0;
CGFloat navigationBarHeight = self.navigationController.navigationBar.frame.size.height;
CGRect frame = self.view.frame;
frame.Origin.y -= navigationBarHeight;
frame.size.height += navigationBarHeight;
self.view.frame = frame;
} completion:NULL];
Swift3
var navAlpha = // Your appropriate calculation
self.navigationController!.navigationBar.backgroundColor = UIColor.red.withAlphaComponent(navAlpha)
Vous pouvez également essayer de définir une vue d’arrière-plan sous la barre de navigation et modifier cette vue directement.
private lazy var backgroundView: UIView = UIView()
...
private func setupNavigationBarBackground() {
guard let navigationBar = navigationController?.navigationBar else { return }
navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationBar.isTranslucent = true
view.addSubview(backgroundView)
backgroundView.alpha = 0
backgroundView.backgroundColor = .red
backgroundView.translatesAutoresizingMaskIntoConstraints = false
backgroundView.topAnchor.constraint(equalTo: topLayoutGuide.topAnchor).isActive = true
backgroundView.bottomAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor).isActive = true
backgroundView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
backgroundView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
}
private func changeNavigationBarAlpha(to alpha: CGFloat) {
backgroundView.alpha = alpha
}
Cela devrait vous donner l'effet que vous désirez:
self.navigationController.navigationBar.alpha = 0.0;
self.navigationController.navigationBar.frame = CGRectMake(0,0,320,0);
N'a pas essayé cela dans une animation, fonctionne dans mon point de vueAppliquez-vous bien, espérons que cela fonctionne.