Question UINavigationController dans ViewController, espace en haut de la vue


Je travaille sur une application universelle et j'essaie de partager autant de code que possible entre les versions iPhone et iPad. Je dois utiliser un TabBarController comme contrôleur de vue racine et même si je souhaite utiliser un SplitViewController dans chacun des onglets, les documents de SplitViewController indiquent qu'il doit s'agir du contrôleur de vue racine. Donc, avec tout cela en tête - comprenez que j'essaie de placer deux contrôleurs de navigation côte à côte et (principalement) de reproduire le comportement / la disposition d'un SplitViewController.

Tout fonctionne très bien, sauf pour la disposition des vues. Lorsque l'application est lancée en mode portrait, tout fonctionne et se redimensionne / se positionne correctement lorsque l'orientation de l'appareil change.

portrait orientation

Si l'application est démarrée dans une autre orientation que UIDeviceOrientationPortrait, la vue s'affiche avec une marge / marge de 20 points au-dessus du contrôleur de navigation. J'ai essayé de régler le cadre à l'exécution sans résultat parfait. Le réglage de l'origine.y du cadre à -20 et l'augmentation de la hauteur de 20 amène la vue au dessus du parent, mais elle laisse un espace de 20 points en bas!

landscape orientation


19
2018-03-03 16:52


origine


Réponses:


J'ai résolu ce problème dans mon application en cachant puis en affichant la barre de navigation après avoir ajouté la vue des contrôleurs de navigation. par exemple.

[parentView addSubview:navController.view];
[navController setNavigationBarHidden:YES];
[navController setNavigationBarHidden:NO];

25
2017-12-02 18:31



Curieusement, ce qui m'aide dans iOS 6 est de sous-classer UINavigationController et d'implémenter cette méthode:

- (BOOL)wantsFullScreenLayout {
    return NO;
}

Décocher "veut que le plein écran" dans mon storyboard n'a pas fait l'affaire, donc je ne sais pas ce qui est différent. Cela pourrait certainement casser dans une future version d'iOS. Mais pour l'instant, je le prendrai.


16
2017-11-17 03:34



UINavigationController est normalement affiché en tant que contrôleur plein écran, ce qui signifie que (affiché en tant que contrôleur de vue racine de la fenêtre), la partie supérieure de sa vue est placée sous la barre d'état. Il positionne ensuite manuellement sa barre de navigation et sa vue de contenu sur ne pas masquer la barre d'état lorsque la barre d'état est visible. Malheureusement, il ne gère pas vraiment les choses correctement lorsqu'il est positionné par un autre contrôleur de vue, il suppose (parfois) qu'il doit laisser cet écart de 20px sans vérifier si sa vue est sous la barre d'état.

La solution est de définir wantsFullScreenLayout sur UINavigationController à NO, il ne tentera même pas de quitter cet espace pour la barre d'état.


3
2018-03-03 17:05



J'ai été capable de brutaliser la force comme suit. Dans viewDidLoad ou loadView:

if (self.navigationController.navigationBar.frame.origin.y > 0.0) {
    self.navigationController.navigationBar.frame = CGRectOffset(self.navigationController.navigationBar.frame, 0.0, -20.0);
}

Et dans viewDidAppear:

if (self.view.superview.frame.origin.y > 44.0) {
    UIView *container = self.view.superview;
    container.frame = CGRectMake(container.frame.origin.x, container.frame.origin.y - 20.0, container.frame.size.width, container.frame.size.height + 20.0);
}

C'est moche, mais ça semble marcher.


3
2018-03-17 00:05



Pour résoudre ce problème, cochez simplement la case Wants Full Screen sur le storyboard.

Le problème apparaît parce que le ParentViewController montre la barre de navigation.

Comme le dit la documentation d’Apple:

Si votre application affiche la barre d'état, la vue se rétrécit afin qu'elle ne soit pas sous la barre d'état. Après tout, si la barre d'état est opaque, il est impossible de voir ou d'interagir avec le contenu situé en dessous. Cependant, si votre application affiche une barre d'état translucide, vous pouvez définir la valeur de la propriété wantsFullScreenLayout de votre contrôleur d'affichage sur YES pour permettre l'affichage de votre vue en plein écran. La barre d'état est dessinée en haut de la vue.


3
2018-02-28 13:07



Je ne suis pas sûr que cela puisse être utile, mais j'ai déjà rencontré des problèmes similaires et j'ai pu résoudre ce problème en définissant le cadre de la vue UINavigationController sur CGRectZero lorsque vous l'ajoutiez à sa vue d'ensemble.

Dans layoutSubviews, je mets à jour le cadre de la vue UINavigationController.


2
2017-08-26 13:53



C'est un problème courant lors de l'ajout de contrôleurs de vue à une barre d'onglets.

De la documentation d'Apple (Contrôleurs de barre d'onglets - Barres d'onglets et disposition plein écran):

Les contrôleurs de barre d'onglets prennent en charge la disposition en plein écran différemment de la façon dont la plupart des autres contrôleurs le prennent en charge. Vous pouvez toujours définir la propriété wantsFullScreenLayout de votre contrôleur d'affichage personnalisé sur YES si vous souhaitez que sa vue se trouve sous la barre d'état ou dans une barre de navigation (le cas échéant). Cependant, la définition de cette propriété sur YES ne provoque pas l'affichage de la vue de la barre d'onglets. Le contrôleur de la barre d'onglets redimensionne toujours votre vue pour l'empêcher de se trouver sous la barre d'onglets.

En termes de code, vous devez procéder comme suit:

UINavigationController *myNavController = [[UINavigationView alloc] init];
myNavController.wantsFullScreenLayout = YES;

//...

NSArray* controllers = [NSArray arrayWithObjects:myNavController, nil];
myTabBarController.viewControllers = controllers;

Si, toutefois, vous rencontrez le problème que lors de l'ouverture de l'application dans l'orientation autre que UIInterfaceOrientationPortrait votre myNavControllerla vue déplace 20 pix de l'écran vers le haut, vous aurez alors défini le contrôleur wantsFullScreenLayout propriété dynamiquement (au lieu de la solution ci-dessus), en fonction de l'orientation initiale. Je le fais en utilisant une variable statique définie dans l'implémentation de votre contrôleur de navigation:

static UIInterfaceOrientation _initialOrientation = -1;

Après cela, vous devez surcharger le viewDidAppear: méthode et définissez la variable de manière appropriée:

- (void)viewDidAppear:(BOOL)animated
{
  if (_initialOrientation == -1)
    _initialOrientation = [[UIApplication sharedApplication] statusBarOrientation];
  self.wantsFullScreenLayout = (_initialOrientation != UIInterfaceOrientationPortrait);

  [super viewDidAppear:animated];
}

J'espère que cela t'aides.


2
2017-11-22 20:08



J'ai rencontré le même problème en ajoutant un UITableView à mon ViewController sur viewDidLoad. Au lieu de saisir l'image de self.view, je l'ai eu comme fenêtre principale pour qu'elle ressemble à ceci

UIWindow *keyWindow = [[[UIApplication sharedApplication] delegate] window];
self.uiTable = [[UITableView alloc] initWithFrame:[keyWindow frame] style:UITableViewStylePlain];

2
2017-09-20 04:22