Problème lié à UINavigationBar / Status Bar dans IOS7

EDIT final

(Plutôt que d’avoir une question trop longue avec des modifications qui apportent une modification finale à des fins de clarification, veuillez consulter d’autres modifications si nécessaire).

Configuration du contrôleur

J’ai une application qui est configurée comme suit:

InitialViewController (sous-classe de ECSlidingViewController )

Contrôleur de navigation principal (sous-classe de UINavigationController )

Principal Home View Controller (sous-classe de UIViewController )


Dans viewDidLoad de initialViewController, je charge le contrôleur de navigation principal avec le contrôleur Home View comme racine.

 self.topViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"MainNavVC"]; 

Le problème

Lors du premier chargement de l’application, la barre d’état et la barre de navigation sont séparées. entrer la description de l'image ici

C’est l’effet souhaité.

Cependant, je charge ensuite un contrôleur de vue modal et le ferme en utilisant les méthodes standard:

 [self performSegueWithIdentifier:@"LoadSelectOpponentVC" sender:self]; 

Puis fermez avec:

 [self dismissViewControllerAnimated:YES completion:nil]; 

À son tour, le contrôleur de navigation principal (qui contient le contrôleur de vue d’accueil) affiche la barre d’état de manière incorrecte et se chevauche:

entrer la description de l'image ici

Essai

  1. Le paramètre plist est défini sur YES – View controller-based status bar appearance
  2. J’ai essayé de paramétrer le paramètre edgesForExtendedLayout sur aucun, mais aucun changement.

Enregistrement

J’ai essayé de déconnecter certains frameworks pour voir où le problème se produit:

Au premier chargement:

VC de navigation principale – Vue – {{0, 0}, {320, 480}}

 Main Nav VC - Nav Bar Frame - {{0, 0}, {320, 44}} Initial VC - View Frame - {{0, 0}, {320, 480}} Home VC - View Frame - {{0, 0}, {320, 480}} -- viewDidLoad Home VC Home VC - View Frame - {{0, 64}, {320, 416}} -- viewWillAppear Home VC --- After Modal is opened/closed ---- Home VC - View Frame - {{0, 64}, {320, 416}} -- viewWillAppear Home VC Main Nav VC - View Frame - {{0, 0}, {320, 480}} -- viewWillAppear Main Nav Main Nav VC - Nav Bar Frame - {{0, 20}, {320, 44}} -- viewWillAppear Main Nav Home VC - View Frame - {{0, 44}, {320, 436}} -- viewDidAppear Home VC 

    Avez-vous essayé la recommandation Apple concernant “Empêcher la barre d’état de couvrir vos vues”: https://developer.apple.com/library/content/qa/qa1797/_index.html

    Et avez-vous jeté un coup d’oeil à “UIBarPositioningDelegate”: https://developer.apple.com/documentation/uikit/uibarpositioningdelegate

    Dans iOS 7.0, UIViewController fonctionne par défaut de cette façon. La vue sera en plein écran si vous utilisez UIViewController dans UINavigationController et que la UINavigationController navigationBar est visible.

    Si la barre de navigation est visible, procédez comme suit. ==>

     self.edgesForExtendedLayout = UIRectEdgeNone 

    Si la barre de navigation est masquée, procédez comme suit. ==>

    Ajustez tous les éléments UIView en décalant 20 points

    Si vous utilisez le générateur Interface, vous pouvez utiliser les deltas iOS6 / 7: D’abord, “afficher sous iOS 6.0”, puis définir un delta de “20” pour obtenir le décalage de +20 dans iOS 7.

    Je suis surpris que personne n’ait encore trouvé la bonne réponse. UIBarPositioningDelegate fonctionne comme un charme! Faites simplement de votre contrôleur de vue un UIBarPositioningDelegate et assignez-le en tant que délégué de la barre. Positionnez la barre à 20 pixels du haut de votre vue. Ajoutez ensuite cette méthode à votre contrôleur de vue (uniquement disponible dans iOS7 +):

     - (UIBarPosition)positionForBar:(id)bar { return UIBarPositionTopAttached; } 

    J’ai eu un problème similaire avec un bouton de menu “hamburger” qui fait glisser le contrôleur de vue principale et avait un contrôleur de vue de menu sur le côté. J’ai constaté que la barre de navigation du contrôleur de vue de menu ne savait pas si la barre d’état était affichée ou non. Je l’ai corrigé en publiant une notification lorsque la barre d’état était affichée et masquait alors

     [self.navigationController setNavigationBarHidden:YES/NO animated:NO]; 

    dans le contrôleur de vue du menu.

    J’ai corrigé un tel problème en utilisant la réponse de cet article: iOS 7 | Boutons de barre de navigation / barre d’outils très proches de la barre d’état

    En utilisant Autolayout, vous devez ignorer la définition d’un nouveau cadre. Vous devez append une contrainte d’espace maximal égale à 20 pour le TopBar pour iOS 7.

    Avez-vous essayé d’append le code suivant à votre méthode viewDidLoad :

     if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) self.edgesForExtendedLayout = UIRectEdgeNone; 

    Il est rapidement expliqué dans la migration d’ Apple vers iOS 7 .

    J’ai répondu longuement à ce problème dans cette réponse à une question similaire . La réponse courte est la suivante: il n’existe aucun moyen d’obtenir le comportement de disposition de barre d’état automatique auquel vous êtes habitué depuis iOS 6 et les versions antérieures. Vous devrez concevoir autour de cela ou trouver un moyen de simuler l’ancien style (je couvre les deux approches).

    Je vous conseille vivement de ne pas modifier manuellement le cadre de la barre de navigation. Laissez UINavigationController gérer cela vous-même. Votre problème est probablement que l’image de votre contrôleur de navigation n’est pas égale aux limites de l’UIScreen.

    Je sais que vous avez ViewController comme VC principal. Mais si quelqu’un utilise UITableviewController et a le même problème, ce code résout le problème:

     self.tableView.contentInset = UIEdgeInsetsMake(20.0f, 0.0f, 0.0f, 0.0f); 

    La solution à ce problème est en réalité très simple. Cela implique de manipuler la valeur center.y de center.y , qui est utilisée nativement par UIKit pour ajuster UINavigationBar à la hauteur de la barre d’état. Pour simplifier, j’ai sous-classé UINavigationBar et ai fait ce qui suit:

     @implementation MyNavigationBar - (void) setCenter:(CGPoint)center { // Anything less than or equal to 22 is something we don't want (below SB height) if(center.y > 22) [super setCenter:center]; } @end 

    Oui eu le même problème suivi toutes les étapes mais pas de changement.

    Vous l’avez fait fonctionner en vous assurant que la mise en forme automatique est correctement configurée pour tout l’écran, pas seulement la vue de dessus / la barre d’outils spécifiée dans

    “Empêcher la barre d’état de couvrir vos vues”: https://developer.apple.com/library/ios/qa/qa1797/_index.html

    Au moins pour toutes les vues situées juste en dessous du Viewcontroller.view principal.

    Il existe un moyen intégré de le faire. Identique à la réponse de Joel Cave, mais élaborée:

    Faites que votre barre de navigation ait une origine Y de 20 points.

    Puis dans le fichier .h:

     @interface XYZViewController : UIViewController  

    Et dans le fichier .m:

     - (void)viewDidLoad { [super viewDidLoad]; self.navigationBar.delegate = self; } - (UIBarPosition)positionForBar:(id)bar { return UIBarPositionTopAttached; } 

    Pour moi, la solution était de déplacer la barre de navigation à 20 points entrer la description de l'image ici

    Je suis un peu en retard pour la fête, mais comme j’ai été confronté au même problème et que c’était le premier résultat de la recherche, je suppose que ma réponse pourrait aider d’autres personnes 🙂

    J’ai corrigé le problème en mettant en œuvre

     - (BOOL)shouldAutorotate { return NO; } 

    dans le contrôleur de vue qui présente le modal.

    Essayez-le, toutes les barres de navigation doivent être translucides ou désactivées.

     [self.navigationController.navigationBar setTranslucent:NO]; 

    Si vous avez conçu votre vue avec un storyboard, vous pouvez résoudre le problème en utilisant XCode. Sélectionnez le widget NavigationBar et décochez “Translucent”.

    entrer la description de l'image ici

    le meilleur moyen est d’append ceci dans la vue que vous avez le problème avec:

     if (self.navigationController.navigationBar.frame.origin.y==0) self.navigationController.navigationBar.frame = CGRectMake(self.navigationController.navigationBar.frame.origin.x, self.navigationController.navigationBar.frame.origin.y, self.navigationController.navigationBar.frame.size.width, 64);