J'essaie d'utiliser la nouvelle fonctionnalité ajoutée dans iOS 8 - masquer la barre de navigation pendant que l'utilisateur fait défiler la vue du tableau (similaire à ce que fait Safari mobile). Je mets la propriété hidesBarsOnSwipe
de UINavigationController
à YES
dans viewDidAppear
méthode de UITableViewController
:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if([self.navigationController respondsToSelector:@selector(hidesBarsOnSwipe)]) {
self.navigationController.hidesBarsOnSwipe = YES;
}
}
La barre de navigation se cache lorsque la vue défile. Jusqu'ici tout va bien. Mais la barre d'état est toujours visible et le contenu de ma vue tabulaire apparaît à travers elle, ce qui semble laid:
J'ai essayé de définir edgesForExtendedLayout
sur UIEdgeRectNone
ou d'ajuster le contentInset
de la vue de table, mais cela n'a pas aidé. Existe-t-il une autre solution pour masquer la barre d'état avec la barre de navigation ou la rendre opaque?
À partir de la réponse d'Anas, j'ai une solution qui fonctionne (je suppose que tableViewController
est votre instance de UITableViewController
):
Dans une sous-classe UINavigationController
(ou potentiellement à partir de tableViewController
):
- (void)viewDidLoad {
if ([self respondsToSelector:@selector(barHideOnSwipeGestureRecognizer)]) {
// iOS 8+
self.hidesBarsOnSwipe = YES;
[self.barHideOnSwipeGestureRecognizer addTarget:self action:@selector(swipe:)];
}
}
- (void)swipe:(UISwipeGestureRecognizer *)recognizer {
BOOL shouldHideStatusBar = self.navigationController.navigationBar.frame.Origin.y < 0;
tableViewController.hideStatusBar = shouldHideStatusBar;
[UIView animateWithDuration:0.2 animations:^{
[tableViewController setNeedsStatusBarAppearanceUpdate];
}];
}
Dans votre tableViewController
:
@property(nonatomic, getter = shouldHideStatusBar) BOOL hideStatusBar;
- (BOOL)prefersStatusBarHidden {
return [self shouldHideStatusBar];
}
Faites-moi savoir si cela ne fonctionne pas pour vous. Quelques choses non évidentes:
self.navigationController.navigationBar.frame.Origin.y
était -44 (la hauteur négative de la barre de navigation) lorsqu'il était masqué et 20 (la hauteur de la barre d'état) lorsqu'il était visible. Il n'y avait pas d'intermédiaire, même pendant les animations, donc une valeur négative == cachée et une valeur non négative == visible.UIViewController
dans un UINavigationController
dans un UITabBarController
, et cela n'a pas fonctionné tant que je n'ai pas remplacé prefersStatusBarHidden
sur le UIViewController
.setNeedsStatusBarAppearanceUpdate
dans un bloc d'animation.En fait, c'est assez facile à faire. Il vous suffit de connecter la propriété de navigation isNavigationBarHidden à la barre d'état.
Objectif-C
- (BOOL)prefersStatusBarHidden {
return self.navigationController.isNavigationBarHidden;
}
Swift <= 2.
override func prefersStatusBarHidden() -> Bool {
return navigationController?.navigationBarHidden ?? false
}
Swift 3.
override var prefersStatusBarHidden: Bool {
return navigationController?.isNavigationBarHidden ?? false
}
Et assurez-vous que "Afficher l'apparence de la barre d'état basée sur le contrôleur" = "OUI" dans le fichier .plist de votre application.
Cette nouvelle propriété est fournie avec son barHideOnSwipeGestureRecognizer
.
À partir de Référence de classe UINavigationController :
Vous pouvez apporter des modifications à l'outil de reconnaissance des gestes selon vos besoins, mais vous ne devez pas modifier son délégué et vous ne devez pas supprimer l'objet cible et l'action par défaut qui sont configurés avec lui. N'essayez pas de remplacer cet identificateur de gestes en remplaçant la propriété.
Mais vous pouvez ajouter une cible:
[self.navigationController setHidesBarsOnSwipe:YES];
[self.navigationController.barHideOnSwipeGestureRecognizer addTarget:self action:@selector(swipeGesture:)];
... et faites ce que vous voulez dans le rappel:
- (void)swipeGesture:(UIPanGestureRecognizer*)gesture
{
// Tweak the status bar
}
Vous devrez peut-être activer manuellement les états de geste, déterminer quand masquer/afficher la barre d'état, etc. J'espère que cela vous aidera!
La réponse de @iOSergey fonctionne parfaitement!
Voici la solution dans Swift 1.2. Ajoutez le code suivant au fichier .Swift des vues:
override func prefersStatusBarHidden() -> Bool {
return self.navigationController!.navigationBarHidden as Bool
}
Si vous souhaitez masquer la barre d'état avec une animation:
override func preferredStatusBarUpdateAnimation() -> UIStatusBarAnimation {
return .Slide
}
override func prefersStatusBarHidden() -> Bool {
return navigationController?.navigationBarHidden ?? false
}
Après beaucoup de lutte, j'ai finalement pu résoudre ce problème.
Ajoutez le code suivant à la fonction viewDidLoad de UIViewController:
// Créer un fond de couleur unie pour la barre d'état (dans Swift Code)
laissez statusFrame = CGRectMake (0.0, 0, self.view.bounds.size.width,
UIApplication.sharedApplication (). StatusBarFrame.size.height)var statusBar = UIView (cadre: statusFrame)
statusBar.backgroundColor = UIColor.whiteColor ()
self.view.addSubview (statusBar)
Ce que vous faites est de créer une barre pleine juste en dessous de la barre de navigation. Lorsque la barre de navigation se déplace vers le haut, la barre pleine se déplace également vers le haut et juste derrière la barre d'état.
Le seul problème est que lorsque vous faites pivoter les côtés de l'écran, la barre blanche est toujours là même si la barre d'état disparaît.
D'accord, j'ai passé toute la journée à faire cela, j'espère que cela aidera certaines personnes. Il y a un barHideOnSwipeGestureRecognizer
. Vous pouvez donc créer un écouteur pour le UIPanGesture
correspondant, en notant que si la barre de navigation est masquée, son origine y est -44.0; sinon, c'est 0 (pas 20 car nous avons caché la barre d'état!).
Dans votre contrôleur de vue (Swift 2):
// Declare at beginning
var curFramePosition: Double!
var showStatusBar: Bool = true
self.navigationController?.barHideOnSwipeGestureRecognizer.addTarget(self, action: "didSwipe:")
...
override func viewDidLoad(){
self.navigationController?.hidesBarsOnSwipe = true
curFramePosition = 0.0 // Not hidden
self.navigationController?.barHideOnSwipeGestureRecognizer.addTarget(self, action: "didSwipe:")
...
}
func didSwipe(swipe: UIPanGestureRecognizer){
// Visible to hidden
if curFramePosition == 0 && self.navigationController?.navigationBar.frame.Origin.y == -44 {
curFramePosition = -44
showStatusBar = false
prefersStatusBarHidden()
setNeedsStatusBarAppearanceUpdate()
}
// Hidden to visible
else if curFramePosition == -44 && self.navigationController?.navigationBar.frame.Origin.y == 0 {
curFramePosition = 0
showStatusBar = true
prefersStatusBarHidden()
setNeedsStatusBarAppearanceUpdate()
}
}
override func prefersStatusBarHidden() -> Bool {
if showStatusBar{
return false
}
return true
}
Une autre façon de le faire consiste simplement à ajouter une autre vue (au-dessus de la vue de table ou de la collection ou de la vue Web ou de la vue de défilement ou autre) et de définir la contrainte supérieure de la vue sur "Superview.Top" et sa contrainte inférieure sur "Top Layout Guide.Bottom", définissez la afficher la couleur d'arrière-plan et c'est tout, vous pouvez même tout faire dans Interface Builder sans aucun code. Et si vous souhaitez répondre à cet événement, vous pouvez ajouter un observateur de chemins de touches au changement de limites de la vue, ou sous-classer la vue et remplacer son régleur de limites ...
Vous devez connecter la navigation isNavigationBarHidden à la barre d'état.
return self.navigationController.isNavigationBarHidden;