web-dev-qa-db-fra.com

la barre d'état iOS 7 entre en collision avec la barre de navigation

Dans mon application, un contrôleur de vue est doté d'une barre de navigation qui est glissée dans le story-board. Cela fonctionnait bien sous iOS 6, mais sous iOS 7, il se présentait ainsi:

ios 7 status bar nav var

La barre d'état et la barre de navigation ne doivent pas entrer en collision. J'ai vu beaucoup de telles questions sur le débordement de pile, mais elles ne m'ont pas beaucoup aidé.

Certaines questions disent que je devrais utiliser ce "self.edgesForExtendedLayout = UIRectEdgeNone;" mais ça n'a pas marché. Certains disent que je devrais supprimer la barre de navigation et l'intégrer dans le contrôleur de navigation, ce que je ne peux pas faire en raison de la manière dont mon programme est mis en œuvre. Certaines solutions suggèrent d'utiliser les limites de la vue et tout, mais cela n'a pas fonctionné pour moi aussi.

Quelle est la seule chose qui peut m'aider à résoudre ce problème? Merci d'avance!

UPDATE: J'ai intégré le contrôleur de vue à l'intérieur d'un contrôleur d'uravigation. Suppression de la barre de navigation précédemment ajoutée manuellement. Maintenant, ça a l'air correct dans le storyboard, mais quand je le lance, il montre ce qui suit:

iOS 7 Navigation Status bar

Il montre le texte d'un autre contrôleur de vue qui se trouve actuellement derrière son contrôleur de vue parent. Signifie sa transparence maintenant. Quelqu'un peut-il signaler ce que je fais mal? 

46
AJ112

La dernière version de l'iOS a apporté de nombreux changements visuels et, du point de vue du développeur, la barre de navigation et la barre d'état sont deux changements notables. 

La barre d'état est maintenant transparente et la barre de navigation derrière elle est visible. L'image de la barre de navigation peut même être étendue derrière la barre d'état. 

Tout d’abord, si vous êtes débutant et que vous venez de commencer le développement sur iOS et que vous ne comprenez pas comment la barre d’état et la barre de navigation fonctionnent, vous pouvez simplement passer par un article de blog ICI que j’ai trouvé très utile. Il contient toutes les informations relatives à la navigation et à la barre d'état dans iOS 7.

J'en viens maintenant à la réponse à votre question. Tout d'abord, je peux voir deux problèmes différents. La première est que votre barre d’état et votre barre de navigation sont toutes deux en collision, comme vous l’indiquez dans la question avec une image. 

PROBLEME: Le problème est que vous avez déjà fait glisser une barre de navigation dans votre contrôleur de vue qui fonctionnait correctement sous iOS 6, mais avec l'arrivée du SDK iOS 7, cette approche entraîne le chevauchement de la barre d'état et de la barre de navigation. L'un et l'autre. 

SOLUTION au premier problème: Vous pouvez utiliser UIBarPositionTopAttached ou des limites de vue et des cadres, je peux également vous suggérer et vous lier à à la documentation Apple et à bla bla mais cela prendrait un certain temps résoudre le problème. 

Le moyen le plus simple et le plus simple de résoudre ce problème consiste simplement à intégrer votre contrôleur de vue dans un contrôleur de navigation et c'est tout. Vous pouvez le faire en sélectionnant simplement le contrôleur de vue et en sélectionnant Editeur> Intégrer dans> Contrôleur de navigation. (S'il y a du contenu sur votre ancienne barre de navigation, vous pouvez d'abord le faire glisser vers le bas, incorporer le contrôleur de vue dans le contrôleur de navigation, puis déplacer les boutons de la barre sur la nouvelle barre de navigation, puis supprimer l'ancienne barre de navigation.)

SOLUTION au deuxième problème: Cette solution concerne votre question spécifique que vous avez mentionnée dans la mise à jour et n'est pas destinée au grand public. Comme vous pouvez le constater, la barre de navigation et la barre d'état ne sont pas visibles et une zone transparente affiche le contrôleur de vue parent. Je ne comprends pas vraiment pourquoi vous faites face à ce problème, mais très probablement à cause de la présence d’une bibliothèque tierce telle que ECSlidingView ou toute autre. Vous pouvez sélectionner ce contrôleur de vue dans votre story-board et définir la couleur d'arrière-plan de la vue sur celle de votre barre de navigation. Cela arrêtera d'afficher le contrôleur de vue parent derrière et votre barre de navigation et votre barre d'état commenceront à s'afficher. Maintenant, vous pouvez couvrir le reste de votre contrôleur de vue avec la vue texte ou tout ce que vous y utilisez. 

J'espère que cela t'aides!

66
KC.

La barre de navigation est trop proche de la barre d'état car à partir de iOS 7, la barre d'état est davantage une superposition sur la vue de l'ensemble du contrôleur de vue. Puisque votre barre de navigation est à (0, 0), la barre d’état s’affiche en haut de la barre de navigation. Pour résoudre ce problème, déplacez simplement la barre de navigation vers le bas (ou, comme d'autres l'ont dit), créez une contrainte entre la barre de navigation et topLayoutGuide.

Ce faisant, vous constaterez qu’il ya maintenant un écart de 20 points entre la barre de navigation et le haut de l’écran. C'est parce que vous venez de déplacer la barre de navigation de 20 points. "Mais UINavigationController peut le faire correctement!" Absolument, et cela en implémentant UIBarPositioningDelegate sur votre contrôleur de vue. C'est un protocole à une méthode qui devrait être implémenté comme ceci:

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

Après avoir ajouté votre contrôleur de vue en tant que délégué pour la barre de navigation, vous remarquerez que la barre de navigation est toujours décalée de 20 points, mais son arrière-plan s'étendra sous la barre d'état, comme dans UINavigationController.

Une autre chose que vous constatez est que la barre de navigation est translucide, ce qui signifie que tout ce qui se trouve sous la barre de navigation sera visible dans une certaine mesure. La propriété translucent sur UINavigationBar est définie sur YES par défaut sur iOS 7. Avant iOS 7, la valeur par défaut était NO.

33
Scott Berrevoets

vous pouvez simplement faire ceci:

1) ajoutez une contrainte entre la barre de navigation et le guide de disposition supérieur (sélectionnez navigationBar, maintenez la touche ctrl enfoncée et accédez à Guide de mise en forme inférieur, retirez la touche ctrl)

Add vertical Contrain

2) sélectionnez espacement vertical:

vertical spacing

3) régler constante sur 0:

vertical spacing constant

Résultat:

result

METTRE &AGRAVE; JOUR

Dans votre fichier AppDelegate, vous pouvez ajouter ceci:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 
{
  // Prevent Navigationbar to cover the view
  UINavigationBar.appearance().translucent = false
}
4
Masterfego

Je vous suggère dans votre méthode viewDidLoad d'essayer:

self.navigationController.navigationBar.translucent = NO;

(par défaut c'est oui maintenant)

https://developer.Apple.com/library/ios/documentation/uikit/reference/UINavigationBar_Class/Reference/UINavigationBar.html#//Apple_ref/occ/instp/UINavigationBar/translucent

3
The dude

Si votre UIViewController N'EST PAS dans une UINavigationController et que vous utilisez UIStoryBoard, vous pouvez définir "iOS 6/7 Deltas" sur 20 pour le delta Y, pour chaque sous-vue devant être décalée par rapport à la UIStatusBar.

enter image description here

2
Nate Potter

Utilisation de Swift :

Comme @Scott Berrevoets l'a dit dans sa réponse, vous devez implémenter la méthode positionForBar dans le protocole UIBarPositioningDelegate, mais comme le protocole UINavigationBarDelegate implémente ce protocole:

public protocol UINavigationBarDelegate : UIBarPositioningDelegate {
   ...
}

Il vous suffit de définir la variable delegate de la variable UINavigationBar que vous avez définie à l'aide de Storyboard et d'implémenter la méthode et c'est fait, comme suit:

class ViewController: UIViewController, UINavigationBarDelegate {

   @IBOutlet weak var navigationBar: UINavigationBar!

   override func viewDidLoad() {
       super.viewDidLoad()
       self.navigationBar.delegate = self 
   }

   override func didReceiveMemoryWarning() {
       super.didReceiveMemoryWarning()
       // Dispose of any resources that can be recreated.
   }

   func positionForBar(bar: UIBarPositioning) -> UIBarPosition {
       return UIBarPosition.TopAttached
   }
}

NOTE: Il vaut la peine de mentionner que si vous définissez la position de l'axe y de la barre de navigation, disons à 40 à partir du haut, elle s'étendra ensuite de bas en haut position, pour simuler le comportement de la UINavigationController, vous devez lui attribuer la valeur 20 à partir du haut.

J'espère que cela vous aidera.

2
Victor Sigler

Cela fonctionne pour moi j'espère que vous avez aussi la même chance:) .
Ajoutez le code ci-dessous dans votre vue.

-(void) viewDidLayoutSubviews
{
    CGRect tmpFram = self.navigationController.navigationBar.frame;
    tmpFram.Origin.y += 20;
    self.navigationController.navigationBar.frame = tmpFram;
}

Il change fondamentalement l'emplacement de la barre de navigation.

2
Jageen

Si cela aide toujours quelqu'un, voici ce qui a fonctionné pour moi pour déplacer légèrement la barre de navigation dans iOS 7 et versions supérieures:

-(void)viewWillLayoutSubviews
{
    float iosVersion = 7.0;
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= iosVersion) {
        // iOS 7+
        CGRect viewFrame = self.view.frame;
        viewFrame.Origin.y += 10;
        self.view.frame = viewFrame;
    }
}

Sur un appareil avec ios 6.1 et inférieur, la barre de navigation reste inchangée, comme auparavant.

Et voici ce que j’ai utilisé pour alléger le contenu de la barre d’état:

-(UIStatusBarStyle)preferredStatusBarStyle{
    return UIStatusBarStyleLightContent;
}
2
derekg

Définissez d'abord UIViewControllerBasedStatusBarAppearance sur NO dans Info.plist . Ensuite, dans la méthode AppDelegate's application:didFinishLaunchingWithOptions:, ajoutez:

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
   [application setStatusBarStyle:UIStatusBarStyleLightContent];
   self.window.clipsToBounds = YES;
   self.window.frame = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height-20);
   self.window.bounds = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height);
 }
 return YES;
2
PJR

Ceci est une nouvelle fonctionnalité avec IOS7. Au lieu de regarder la barre de navigation de 20 px dans IOS7, fixant à 0 px. En guise de solution, déplacez l’ensemble de la vue sur 20 px ou utilisez l’image pour barre de navigation d’une hauteur de 64px.

2
PgmFreek

dans la fenêtre iOS précédente, démarrez après la barre d'état et dans iOS 7, la fenêtre démarre à partir de 0px dans la version précédente (iPhone 5 et versions ultérieures), vous devez donc commencer à organiser la vue après 2o px ou à partir de 20 pixels.

vous pouvez écrire ci-dessous le code dans rootviewcontroller ou dans tout viewcontroller pour une vue définie à partir de 20px

#define IOS7_HEIGHT             64

- (void)viewDidLayoutSubviews {
    NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
    if ([currSysVer compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending)
    {
        CGRect frame=[self.view frame];
        if (frame.Origin.y!=IOS7_HEIGHT) {

            frame.Origin.y = IOS7_HEIGHT;
            frame.size.height -= IOS7_HEIGHT;
            [self.view setFrame:frame];
            [self.view layoutSubviews];
        }
    }
}

ici height est 64 car 20 pour la barre d'état et 44 pour la barre de navigation . essayez ci-dessous le code cela vous aidera. et votre problème sera résolu. 

1
Pratik

Pour ceux qui rencontrent des problèmes pour mettre en œuvre la solution de @Masterfego (qui est également officielle, mais j'ai eu des problèmes avec Xcode 6.3 et des contraintes automatiques), voici ce que j'ai fait:

J'ai un UIViewController avec une barre de navigation ajoutée. J'ai sélectionné la barre de NAvigation et ajouté une contrainte de hauteur de 64px. Nous voyons plus tard un avertissement que la barre de navigation sera plus haute (mais c'est ce que nous faisons). Enfin, vous pouvez voir que la barre d'état a l'air agréable et a la même couleur que la barre de navigation. :) 

PS: Je ne peux pas encore publier d’images. 

1
cduguet

Vous pouvez probablement créer des contraintes liées au guide de présentation supérieur pour spécifier la position de la barre de navigation par rapport à la barre d'état. Consultez la section Guide de transition de l'interface utilisateur iOS 7: Apparence et comportement pour plus d'informations sur l'utilisation des guides de présentation.

0
Greg

c’est la meilleure réponse… .. Mais je voulais savoir comment utiliser une variable Storyboard et y glisser UINavigationBar . Lorsque j’ai implémenté la méthode déléguée et que j’ai défini le résultat renvoyé sur UIBarPositionTopAttached, cela ne fonctionnait pas.

- (void)viewDidLoad{
    self.navigationbar.delegate = self;
}
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar{
    NSLog(@"Got it");
    //
    //    CGRect frame = self.navigaitonBar.frame;
    //
    //    frame = CGRectMake(0, 20, CGRectGetWidth(frame), CGRectGetHeight(frame));
    //    self.navigaitonBar.frame = frame;
    //
    //    NSLog(@"frame %f",frame.Origin.y);
    return UIBarPositionTopAttached;
}
0
rbbtsn0w

Si vous utilisez Xcode 6 et Swift, vous pouvez le créer:

  1. Ouvrez le fichier info.plist de votre application.
  2. Ajoutez une clé booléenne ViewControllerBasedStatusBarAppearance si elle n’existe pas et attribuez la valeur «NO».
  3. Ajoutez la clé «Style de la barre d’état» si elle n’existe pas et sélectionnez la valeur «Style noir opaque».
0
Alexsander

J'étais confronté à un problème lorsque le plein écran ModalViewController ouvrait à partir de ma MainViewController, NavigationBar était modifié lorsque l'utilisateur revenait à MainViewController de ModalViewController.

Le problème que j'ai remarqué est que la hauteur de la barre d'état n'était pas incluse lorsque l'utilisateur est revenu à MainViewController. Veuillez déboguer et vérifier l’origine de votre NavigationBar avant et après votre retour à votre ViewController.

// This method will adjust navigation bar and view content.
    private func adjustNavigationControllerIfNeeded() {

        var frame = self.view.frame
        let navigationBarHeight = self.navigationController!.navigationBar.frame.size.height

        if(frame.Origin.y == navigationBarHeight && !UIApplication.shared.isStatusBarHidden) { 

   // If status bar height is not included but it is showing then we have to adjust 
      our Navigation controller properly

            print("Adjusting navigation controller")
            let statusBarHeight = UIApplication.shared.statusBarFrame.height

            frame.Origin.y += statusBarHeight // Start view below navigation bar
            frame.size.height -= statusBarHeight
            self.view.frame = frame

            self.navigationController!.navigationBar.frame.Origin.y = statusBarHeight // Move navigation bar
        }
    }

Et appelez-le à partir de la méthode viewWillAppear -

override func viewWillAppear(_ animated: Bool) {

        super.viewWillAppear(animated)
        self.adjustNavigationControllerIfNeeded()
}
0
Rahul