39 votes

Sur iOS 7, le fait de pousser un contrôleur avec une barre d'outils laisse un espace inutilisable s'il est finalement contenu dans un contrôleur de barre d'onglets.

Dans mon application iOS, ma fenêtre est rootViewController est une barre d'onglet contrôleur avec l'une hiérarchie comme ceci:

  • UITabBarController
    • UINavigationController 1
      • FirstContentController
    • UINavigationController 2
      • ...
    • UINavigationController 3
      • ...
    • ...

Lorsque l'utilisateur appuie sur un certain rang, sur FirstContentController, une instance de SecondController sera poussé sur sa manette de navigation. SecondContentController jeux hidesBottomBarWhenPushed de YES ses init méthode et définit self.navigationController.toolbarHidden de NO en viewWillAppear:.

Dans iOS 6, l'utilisateur, appuyez sur la ligne en FirstController et SecondController permettrait d'obtenir poussé sur la valeur liquidative du contrôleur. Parce qu'il a hidesBottomBarWhenPushed ensemble, il serait de masquer la barre d'onglets et, par le moment de la transition de l'animation était complet, SecondController serait sur l'écran avec sa barre d'outils visible.

Cependant, lors de l'essai de cette sous iOS 7, hidesBottomBarWhenPusheds'comportement semble avoir changé. Ce que je vois maintenant est:

  • la barre d'onglet cache, comme prévu
  • la barre d'outils s'affiche, comme prévu
  • un écart d'espace inutilisable exactement 49 pixels de haut (la hauteur de la barre d'onglet) apparaît entre la barre d'outils et l'affichage du contenu

L'écart est complètement inutilisable - il ne répond pas à la touche et si j'ai mis en clipsToBounds OUI sur l'écran principal, rien n'attire l'il. Après beaucoup de débogage et l'examen de la sous-vue des hiérarchies, il ressemble à iOS de redimensionnement automatique mécanisme redimensionne la vue du contrôleur de la vue à une hauteur de 411 (sur l'iPhone 5). Il convient de 460 à atteindre tout en bas de la barre d'outils, mais le système de mise en page semble être compris comme "un fantôme" 49 pixels de haut, la barre d'onglets.

Ce problème se produit uniquement si le point de vue contrôleur dispose d'un onglet de la barre de contrôleur comme l'une de ses conteneurs parents.

Sur iOS 7, comment puis-je avoir la barre d'onglets disparaissent et une barre d'outils de façon transparente pour glisser en place, lorsqu'un nouveau contrôleur est poussé, et ont encore la vue de reprendre la totalité de l'espace entre l'élément de navigation et la barre d'outils?

Mise à JOUR

Après enquête, cela se produit uniquement si SecondController de l' edgesForExtendedLayout est définie à l' UIRectEdgeNone. Cependant, à moins que j'ai mis que la propriété d' UIRectEdgeNone, le point de vue de l'image est trop long et s'étend en dessous de la barre d'outils, où il ne peut pas être vu ou interagi avec.

19voto

srik Points 696

J'ai trouvé que l'ajout de 2 lignes de code en viewDidLoad de SecondViewController (où vous voulez cacher TabBar mais afficher la barre d'outil) résout le problème.

self.extendedLayoutIncludesOpaqueBars = YES;
self.edgesForExtendedLayout = UIRectEdgeBottom;

Mon viewDidLoad de SecondViewController est comme suit:

- (void)viewDidLoad {
    [super viewDidLoad];
    // These 2 lines made the difference
    self.extendedLayoutIncludesOpaqueBars = YES;
    self.edgesForExtendedLayout = UIRectEdgeBottom;

    // The usual configuration
    self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
    self.navigationController.navigationBar.translucent = NO;

    self.navigationController.toolbarHidden = NO;
    self.navigationController.toolbar.barStyle = UIBarStyleBlack;
    self.navigationController.toolbar.translucent = NO;
    .
    .
}

Mais vous avez besoin de fixer le cadre de la vue manuellement car cela cause de la taille (320x504). Ce qui signifie qu'elle s'étend même derrière la barre d'outils. Si ce n'est pas un problème pour vous, alors cette solution devrait fonctionner.

17voto

Leo Natan Points 25262

Vous n'aimerez pas cette réponse , Ce n'est pas la réponse que vous voulez, mais après quelques recherches sur le masquage de la barre d'onglet dans iOS7, ma conclusion est la suivante: ne pas!

Barres d'onglets n'ont jamais été destiné à être caché - après tout, pourquoi avoir un UITabBarController si vous souhaitez masquer la barre d'onglets. L' hidesBottomBarWhenPushed sur la vue des contrôleurs est pour cacher la barre inférieure de la manette de navigation, pas de barres d'onglets. À partir de la documentation:

Une-vue-contrôleur ajouté en tant qu'enfant d' une manette de navigation peut afficher une option de la barre d'outils au bas de l'écran. La valeur de cette propriété sur la plus haute vue-contrôleur détermine si la barre d'outils est visible. Si la valeur de cette propriété est OUI, la barre d'outils est masquée. Si la valeur de cette propriété n'est PAS, la barre est visible.

En outre, vous êtes averti de ne pas modifier la barre d'onglet objet directement. Encore une fois, à partir de la documentation:

Vous ne devriez jamais tenter de manipuler les UITabBar objet lui-même stocké dans cette propriété.

C'est exactement ce que vous faites lors de la configuration de la cacher.

Dans iOS6 cela a fonctionné, mais maintenant dans iOS7, il ne le fait pas. Et il semble très enclins à faire des erreurs afin de les masquer. Lorsque vous avez enfin réussi à le cacher, si l'application passe à l'arrière plan et le rendement de la Pomme de la logique de présentation des remplacements de vos modifications.

Ma suggestion est d'afficher vos données sous forme modale. Dans iOS7, vous pouvez créer des transitions personnalisées, donc si il est important pour vous d'avoir une poussée de transition, vous pouvez le recréer vous-même, bien que ce soit un peu plus haut. Normal modal de transition est quelque chose que les utilisateurs sont familiers, et correspond en fait à ce cas mieux que de pousser qui cache la barre d'onglet.


Une autre solution est d'utiliser une barre d'outils au lieu d'une barre d'onglet. Si vous utilisez la manette de navigation de la barre d'outils pour vos onglets, vous pouvez ensuite utiliser hidesBottomBarWhenPushed que vous avez besoin et il vous donnera le comportement que vous attendez.

8voto

Ah Ryun Moon Points 96

Décochez la case "Masquer le fond de barres push" et de définir votre autoconstraints que si il y a une barre d'onglet. Puis dans "ViewDidLoad" de la commande que vous souhaitez masquer l'onglet système de la barre, placez le code suivant.

[self.tabBarController.tabBar setFrame:CGRectZero];

Cela permet de s'assurer de la barre d'onglet accepte encore l'interaction de l'utilisateur, mais pas encore visible pour les utilisateurs. (d'autres solutions, telles que le réglage à 0, alpha ou caché onglet render bar inutile) Maintenant le autoconstaraints assurez-vous que votre vue s'affiche correctement avec l'onglet hauteur de la barre à zéro.

5voto

Darren Points 13973

C'est un bug dans iOS 7 UIKit en raison de cette combinaison particulière de:

  • UITabBarController
  • hidesBottomBarWhenPushed = OUI
  • edgesForExtendedLayout = UIRectEdgeNone
  • UINavigationController de la barre d'outils

Vous devez soumettre un rapport de bogue avec Apple et d'inclure votre code d'exemple.

Pour contourner le bug, vous devez supprimer l'une de ces quatre conditions. Deux options possibles:

  1. Fixer la mise en page de votre "second" - vue-contrôleur pour qu'il fonctionne correctement lors de l' edgesForExtendedLayout est définie à l' UIRectEdgeAll. Cela pourrait être aussi simple que la définition de l' contentInset sur un parchemin de point de vue.

  2. N'utilisez pas de UINavigationController intégré dans la barre d'outils. Au lieu de cela, créez un UIToolBar instance et l'ajouter manuellement à votre second point de vue du contrôleur de vue.

2voto

Hackmodford Points 1321

La clé de cette énigme est que la taille de navigationcontroller.view.frame ne change pas. Aller du Gist de Batkin est un de mes points essentiels .

FirstViewController.m

 #import "FirstController.h"
#import "SecondController.h"

@implementation FirstController

-(id)init
{
    if( (self = [super init]) )
    {
        self.tabBarItem.title = @"Foo";
        self.tabBarItem.image = [UIImage imageNamed:@"Tab Icon.png"];
    }

    return self;
}

-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
{
    return 1;
}

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
    UITableViewCell* cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];

    cell.textLabel.text = @"Click";

    return cell;
}

-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
    SecondController* controller = [[SecondController alloc] init];
    self.tabBarController.tabBar.hidden = YES;
    [self.navigationController pushViewController:controller animated:YES];
}

@end
 

SecondViewController.m

 #import "SecondController.h"

@implementation SecondController

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    self.view.backgroundColor = [UIColor redColor];
    self.view.clipsToBounds = YES;

    /* ENTER VORTEX OF DESPAIR */

    // without this, there's no gap, but the view continues under the tool 
    // bar; with it, I get the 49-pixel gap thats making my life miserable

    self.edgesForExtendedLayout = UIRectEdgeNone;

    //this resizes the navigation controller to fill the void left by the tab bar.
    CGRect newFrame = self.navigationController.view.frame;
    newFrame.size.height = newFrame.size.height + 49;
    self.navigationController.view.frame = newFrame;

    /* EXIT VORTEX OF DESPAIR */

    self.navigationController.toolbarItems = @[
                                               [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:nil action:nil]
                                               ];


}

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    self.navigationController.toolbarHidden = NO;

    // will log a height of 411, instead of the desired 460
    NSLog(@"frame: %@", NSStringFromCGRect(self.view.frame));
    NSLog(@"frame: %@", NSStringFromCGRect(self.navigationController.view.frame));
}

-(void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    self.tabBarController.tabBar.hidden = NO;
    self.navigationController.toolbarHidden = YES;

    //this resizes the navigation controller back to normal.
    CGRect newFrame = self.navigationController.view.frame;
    newFrame.size.height = newFrame.size.height - 49;
    self.navigationController.view.frame = newFrame;

    //this is optional and resizes the view to fill the void left by the missing toolbar.
    CGRect newViewFrame = self.view.frame;
    newViewFrame.size.height = newViewFrame.size.height + 49;
    self.view.frame = newViewFrame;

}

@end
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X