web-dev-qa-db-fra.com

Iphone: Est-il possible de cacher le TabBar? (Pré-iOS 8)

J'ai une application qui utilise une UITabBarController pour basculer entre les modes. Dans un certain mode, j'aimerais masquer la barre d'onglets jusqu'à ce que les étapes de ce mode soient terminées. Notez que je n'utilise pas de contrôleur de navigation. Je ne peux donc pas utiliser la méthode setHidesBottomBarWhenPushed sur le contrôleur de navigation pour masquer la barre d'onglets.

Avant iOS 8, lorsque je tente de masquer la barre d’arrière en utilisant:

self.tabBarController.tabBar.hidden = YES

la barre de tabulation disparaît, mais il reste une zone vide de 50 pixels au bas de l'écran à l'emplacement de la barre de tabulation. Je n'arrive pas à comprendre comment remplir cette zone. Tous les éléments de l'interface utilisateur situés dans cette zone sont coupés et ne peuvent pas être vus.

Des idées si c'est même possible? J'aimerais vraiment rester à l'écart du contrôleur de navigation.

34
Steve

Voici mon code pour cela:

Ceci est bien sûr une erreur avec le va sur dans la hiérarchie de vues du contrôleur. Cela pourrait changer/casser. Ceci utilise des API définies, donc Apple ne s'en soucie pas, mais ils ne se soucieront pas non plus de casser votre code.

- (void)hideTabBar {
  UITabBar *tabBar = self.tabBarController.tabBar;
  UIView *parent = tabBar.superview; // UILayoutContainerView
  UIView *content = [parent.subviews objectAtIndex:0];  // UITransitionView
  UIView *window = parent.superview;

  [UIView animateWithDuration:0.5
                   animations:^{
                     CGRect tabFrame = tabBar.frame;
                     tabFrame.Origin.y = CGRectGetMaxY(window.bounds);
                     tabBar.frame = tabFrame;
                     content.frame = window.bounds;
                   }];

  // 1
}

- (void)showTabBar {
  UITabBar *tabBar = self.tabBarController.tabBar;
  UIView *parent = tabBar.superview; // UILayoutContainerView
  UIView *content = [parent.subviews objectAtIndex:0];  // UITransitionView
  UIView *window = parent.superview;

  [UIView animateWithDuration:0.5
                   animations:^{
                     CGRect tabFrame = tabBar.frame;
                     tabFrame.Origin.y = CGRectGetMaxY(window.bounds) - CGRectGetHeight(tabBar.frame);
                     tabBar.frame = tabFrame;

                     CGRect contentFrame = content.frame;
                     contentFrame.size.height -= tabFrame.size.height;
                   }];

  // 2
}

Edit : Un utilisateur anonyme a suggéré l’ajout suivant pour 7.0 (je ne l’ai pas testé et je ne saurais dire s’il s’agit d’une solution de contournement ou d’une implémentation idéale):

// 1. To Hide the black line in IOS7 only, this extra bit is required
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
    [self.tabBarController.tabBar setTranslucent:YES];
}  

// 2. For IOS 7 only
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
    [self.tabBarController.tabBar setTranslucent:NO];
}

Edit : Pas du tout testé dans la version 8.x et probablement pas dans certaines mises en page.

37
bshirley

Comme Steve, je n'ai pas trouvé de moyen propre de le faire (même si Apple Photopicker fait quelque chose de similaire). Voici ce que j'ai fait:

 if (systemAction)
  {
    // Reveal tab bar back
    CGRect bounds = [[UIScreen mainScreen] bounds];
    CGRect tabBarFrame = self.tabBarController.tabBar.frame;
    self.tabBarController.view.frame = CGRectMake(0,0,bounds.size.width,bounds.size.height);
    self.toolBar.hidden = YES;
    systemAction = NO;
  }
  else
  {
    //hide tab bar
    CGRect bounds = [[UIScreen mainScreen] bounds];
    CGRect tabBarFrame = self.tabBarController.tabBar.frame;
    CGRect navigationBarFrame = self.navigationController.navigationBar.frame;
    self.tabBarController.view.frame = CGRectMake(0,0,bounds.size.width,bounds.size.height+tabBarFrame.size.height);
    self.toolBar.hidden = NO;
    CGRect frame = self.toolBar.frame;
    frame.Origin.y = bounds.size.height - frame.size.height - navigationBarFrame.size.height;
    self.toolBar.frame = frame;
    systemAction = YES;
  }

Il pousse la vue vers le bas afin que je puisse afficher une barre d’outils (et non la masquer). Évidemment, il s’agit uniquement de la "vue racine" d’une barre à onglets + du contrôleur de navigation. Pour toutes les vues suivantes, vous pouvez définir le paramètre 'hidesBottomBarWhenPushed' sur le contrôleur de vue que vous poussez.

9
Terence

J'ai essayé un certain nombre des solutions ci-dessus, mais aucune joie dans iOS 8. Je trouve ce paramètre dans viewWillAppear qui fonctionne pour moi. Devrait fonctionner sous iOS 7 à la suite de l'introduction de extendedLayoutIncludesOpaqueBars. 

    self.extendedLayoutIncludesOpaqueBars = true
    self.tabBarController?.tabBar.isHidden = true
    self.tabBarController?.tabBar.isOpaque = true

et si vous devez réactiver TabBars lorsque vous quittez les éléments suivants dans viewWillDisappear.

    self.tabBarController?.tabBar.isHidden = false
    self.tabBarController?.tabBar.isOpaque = false

J'utilise ceci pour permettre à un retour d'une transition de garder la TabBar masquée. Non utilisé dans une action de bouton mais si, comme moi, vous ne trouvez rien ci-dessus, cela fonctionne maintenant, cela pourrait être la base d'une solution programmable. 

8
GAllan

Il est un peu tard dans la journée, mais de toutes les réponses à la question que j'ai explorée cet après-midi, c'est celle qui a le mieux fonctionné pour moi.

Comment cacher uitabbarcontroller

// Method call
[self hideTabBar:self.tabBarController];   

// Method implementations
- (void)hideTabBar:(UITabBarController *) tabbarcontroller
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.5];

    for(UIView *view in tabbarcontroller.view.subviews)
    {
        if([view isKindOfClass:[UITabBar class]])
        {
            [view setFrame:CGRectMake(view.frame.Origin.x, 480, view.frame.size.width, view.frame.size.height)];
        } 
        else 
        {
            [view setFrame:CGRectMake(view.frame.Origin.x, view.frame.Origin.y, view.frame.size.width, 480)];
        }
    }

    [UIView commitAnimations];   
}

- (void)showTabBar:(UITabBarController *) tabbarcontroller
{       
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.5];
    for(UIView *view in tabbarcontroller.view.subviews)
    {
        NSLog(@"%@", view);

        if([view isKindOfClass:[UITabBar class]])
        {
            [view setFrame:CGRectMake(view.frame.Origin.x, 431, view.frame.size.width, view.frame.size.height)];

        } 
        else 
        {
            [view setFrame:CGRectMake(view.frame.Origin.x, view.frame.Origin.y, view.frame.size.width, 431)];
        }
    }

    [UIView commitAnimations]; 
}
4
Ted

Je n'utilise que cette ligne pour y parvenir. J'utilise la méthode prepareForSegue avant d'afficher le contrôleur de vue ayant la barre d'onglets.

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if([segue.identifier isEqualToString:@"showLogin"]){
        [segue.destinationViewController setHidesBottomBarWhenPushed:YES];
    }
}
4
coder9

J'avais pratiquement travaillé sur le même cas, utilisé le code de http://www.developers-life.com/hide-uitabbarcontrolleruitabbar-with-animation.html et l'avais amélioré en fonction de mes besoins aider les autres aussi.

J'utilise UISplitViewController comme contrôleur de vue racine et sa partie de détail est un UITabBarController. J'ai dû masquer la barre de tabulation en mode portrait:

// In UITabBarController's custom implementation add following method, 
// this method is all that will do the trick, just call this method 
// whenever tabbar needs to be hidden/shown 
- (void) hidetabbar:(NSNumber*)isHidden {
    UITabBarController *tabBarController=self;

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.5];

    CGRect tabbarFrame=CGRectZero;
    for(UIView *theView in tabBarController.view.subviews) {
        //NSLog(@"%@", view);
        if([theView isKindOfClass:[UITabBar class]]) {
            tabbarFrame=theView.frame;
            if ([isHidden boolValue]) {
                tabbarFrame=CGRectMake(tabbarFrame.Origin.x, 
                                       tabBarController.view.frame.size.height, 
                                       tabbarFrame.size.width, 
                                       tabbarFrame.size.height);
            } else {
                tabbarFrame=CGRectMake(tabbarFrame.Origin.x, 
                                       tabBarController.view.frame.size.height - tabbarFrame.size.height, 
                                       tabbarFrame.size.width,
                                       tabbarFrame.size.height);
            }
            theView.frame=tabbarFrame;
            break;
        }
    }

    for(UIView *theView in tabBarController.view.subviews) {
        if(![theView isKindOfClass:[UITabBar class]]) {
            CGRect theViewFrame=theView.frame;
            if ([isHidden boolValue]) {
                theViewFrame=CGRectMake(theViewFrame.Origin.x, 
                                        theViewFrame.Origin.y, 
                                        theViewFrame.size.width, 
                                        theViewFrame.size.height + tabbarFrame.size.height);
            } else {
                theViewFrame=CGRectMake(theViewFrame.Origin.x, 
                                        theViewFrame.Origin.y, 
                                        theViewFrame.size.width, 
                                        theViewFrame.size.height - tabbarFrame.size.height);
            }
            theView.frame=theViewFrame;
        }
    }
    [UIView commitAnimations];
}

J'ai utilisé le code suivant pour appeler la méthode hidetabbar: 

//In my UISplitViewController's custom implementation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    @synchronized(self){
    //change the self.splitDetailController to your UITabBarController's object
    [self.splitDetailController 
     performSelector:@selector(hidetabbar:) 
     withObject:[NSNumber numberWithBool:UIInterfaceOrientationIsLandscape(interfaceOrientation)]
     afterDelay:0.5];
    }
    return YES;
}

J'ai testé ce code pour fonctionner dans le simulateur seulement, laissez-moi savoir si cela fonctionne aussi sur l'appareil ;-)

3
Abduliam Rehmanius

Vous pouvez créer une catégorie de tabulation et afficher/masquer facilement. et vous pouvez accéder à la vue complète.

créer la catégorie #import "UITabBarController+HideTabBar.h"

@implementation UITabBarController (HideTabBar)

- (void)hideTabBarAnimated:(BOOL)animated
{
    CGRect statusbarFrame = [UIApplication sharedApplication].statusBarFrame;
    CGRect tabBarControllerFrame = self.view.frame;
    if (statusbarFrame.size.height>20)
    {
        tabBarControllerFrame.size.height =  screenSize.size.height + self.tabBar.frame.size.height - 20.0;
    }
    else
    {
        tabBarControllerFrame.size.height = screenSize.size.height + self.tabBar.frame.size.height ;
    }

    if (animated) {
        [UIView animateWithDuration:0.2 animations:^{
            [self.view setFrame:tabBarControllerFrame];
        } completion:^(BOOL finished) {

        }];
    }
    else
        [self.view setFrame:tabBarControllerFrame];
}

- (void)showTabBarAnimated:(BOOL)animated {
    CGRect statusbarFrame = [UIApplication sharedApplication].statusBarFrame;
    CGRect tabBarControllerFrame = self.view.frame;
    if (statusbarFrame.size.height>20)
    {
        tabBarControllerFrame.size.height =  screenSize.size.height - 20.0;
    }
    else
    {
        tabBarControllerFrame.size.height = screenSize.size.height ;
    }

    if (animated) {
        [UIView animateWithDuration:0.2 animations:^{
            [self.view setFrame:tabBarControllerFrame];
        } completion:^(BOOL finished) {

        }];
    }
    else
        [self.view setFrame:tabBarControllerFrame];
}
@end

Remarque : use statusbarFrame est utilisé lorsque hotspot ou call est activé afin que la barre de tabulation ne soit pas réduite.

Maintenant, importez la catégorie dans laquelle vous voulez utiliser des méthodes et appelez simplement les méthodes ci-dessous pour masquer ou afficher la barre de tabulation.

[self.tabBarController hideTabBarAnimated:YES];

[self.tabBarController showTabBarAnimated:YES];

J'espère que cela t'aides.

0

le masque de redimensionnement automatique est énuméré. Essayez de définir toutes les options et de vérifier si l'option de redimensionnement automatique des sous-vues est cochée dans la vue parente

0
user2159978

J'espère que ça marche.

 @ interface UITabBarController (Ajouts) 

- (void) setTabBarHidden: (BOOL) masqué animé: (BOOL) animé; 

 @ end 

 @ implémentation UITabBarController ( Ajouts) 

- (void) setTabBarHidden: (BOOL) caché animé: (BOOL) animé 
 {
 si (animé) 
 {
 [UIView beginAnimations: nil contexte: nil]; 
 } 
 si (caché) 
 {

 self.tabBar.frame = CGRectMake (self.tabBar.frame.Origin.x, self.tabBar.superview.frame.size.height, self.tabBar.bound.size.width, self.tabBar.bound.size.height) ; 
 } 
 autre
 {
 self.tabBar.frame = CGRectMake (self.tabBar.frame.Origin.x, self.tabBar.superview.frame.size.height - self.tabBar.frame.size.height + 10, self.tabBar.bounds.size. largeur, self.tabBar.bounds.size.height); 
 } 
 si (animé) 
 {
 [UIView commitAnimations]; 
 } 

} 

0
Amit Tandel

La solution évidente, en gardant votre architecture d'origine, aurait été de présenter cette vue sous forme modale:

- (void)tabBarController:(UITabBarController *)tb
 didSelectViewController:(UIViewController *)vc {
    if (tb.selectedIndex == MODALONE) {
        UIViewController* mod = 
            [[UIViewController alloc] initWithNibName: @"ModalView" 
                                               bundle: nil];
        [tb presentModalViewController:mod animated:NO];
        [mod release];
    }
}

La vue couvre maintenant la totalité de l'écran (à l'exception de la barre d'état s'il en existe une), y compris la barre d'onglets. Il semble donc que la barre d'onglets s'est effacée lorsque l'utilisateur a appuyé sur cet élément.

0
matt

Voici ma solution (mon contrôleur de vue par onglets se trouve à l'intérieur du contrôleur de navigation pour une bonne mesure) ... J'ai donc sous-classé UITabBarController et je l'ai fait ... en exposant la méthode -setTabBarHidden:

- (void)setTabBarHidden:(BOOL)hidden {
    _tabBarHidden = hidden;

    [UIView performWithoutAnimation:^{
        [self adjustViews];
    }];

}

- (void)adjustViews {
    if ( _tabBarHidden ) {
        CGRect f = self.tabBar.frame;

        // move tab bar offscreen
        f.Origin.y = CGRectGetMaxY(self.view.frame);
        self.tabBar.frame = f;

        // adjust current view frame
        self.selectedViewController.view.frame = self.view.frame;
    } else {
        CGRect f = self.tabBar.frame;

        // move tab bar on screen
        f.Origin.y = CGRectGetMaxY(self.view.frame) - (CGRectGetMaxY(self.tabBar.bounds) + CGRectGetMaxY(self.navigationController.navigationBar.frame));
        self.tabBar.frame = f;

        // adjust current view frame
        f = self.view.bounds;
        f.size.height -= CGRectGetMaxY(self.tabBar.bounds);
        self.selectedViewController.view.frame = f;
    }
}

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];

    [UIView performWithoutAnimation:^{
        [self adjustViews];
    }];
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    [UIView performWithoutAnimation:^{
        [self adjustViews];
    }];
}
0
Cherpak Evgeny

mettre la déclaration dans la méthode init de UIViewController

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        self.hidesBottomBarWhenPushed = true
        setupDependencyConfigurator()
    }
0
ASHISH mittal

Le masque autoResizing est-il défini dans la vue secondaire?

view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

Quelque chose comme ça devrait faire l'affaire et permettre à la vue située au sommet de la pile de redimensionner.

0
MystikSpiral