2011-03-11 18 views
72

Tengo un problema con UITabBarController. En mi aplicación, quiero ocultarlo pero sin usar hidesBottomBarWhenPushed porque quiero ocultarlo cuando lo presioné. Por ejemplo, quiero ocultarlo cuando presiono un botón Ocultar en mi aplicación.Cómo ocultar uitabbarcontroller

He leído muchos artículos en Google, pero no puedo averiguar cómo puedo hacer esto.

+0

posible duplicado de [Iphone: ¿Es posible ocultar el TabBar?] (Http://stackoverflow.com/questions/1982172/iphone-is-it-possible-to-hide-the-tabbar) – Pang

Respuesta

149

estoy pegando este código de mi trabajo ... se puede llamar a estos métodos para ocultar y mostrar la tabBarController .... sólo tiene que pasar instancia tabBarController a estas funciones ..

// 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]; 
} 
+0

¿Apple te permite hacerlo? Quiero decir, tabbar debe ser de solo lectura ... solo me pregunto si mi aplicación va a ser rechazada – mateusmaso

+3

, intento esta solución. cuando llame al método hideTabbar(), la barra de pestañas se esconde pero muestra el espacio negro en la parte inferior (coloque la misma barra de pestañas).¿Cómo puedo arreglar esto? – Thunderbird

32

En su método de acción para el botón:

[self.tabBarController.tabBar setHidden:YES]; 
+2

Este método funciona en iOS 7, pero en iOS 6 dejará un gran espacio donde estaba la barra de pestañas. –

3

puede empujar un controlador de vista modal

[self presentModalViewController:myFullscreenViewController animated:YES]; 

esto creará una nueva vista de pantalla completa por encima de su actual.

despedir ist con dismissModalViewController:animated:

9

respuesta de Saurabh anterior se puede extender a trabajar también en orientación horizontal: 012

+ (void) hideTabBar:(UITabBarController *) tabbarcontroller { 

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

    //Support for landscape views 
    int orientation = [[UIDevice currentDevice] orientation]; 
    int x_pos = 480; 
    if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight) { 
     x_pos = 320; 
    } 

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

`

Los números x_pos correspondientes para showTabBar() son 431 y 271.

58

Respuesta modificada de Setomidor para trabajar en paisajes, retratos y iPad (los valores 320 y 480 solo funcionan en iPhone).

- (void) hideTabBar:(UITabBarController *) tabbarcontroller 
{ 
    CGRect screenRect = [[UIScreen mainScreen] bounds]; 

    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationDuration:0.5]; 
    float fHeight = screenRect.size.height; 
    if( UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) 
    { 
     fHeight = screenRect.size.width; 
    } 

    for(UIView *view in tabbarcontroller.view.subviews) 
    { 
     if([view isKindOfClass:[UITabBar class]]) 
     { 
      [view setFrame:CGRectMake(view.frame.origin.x, fHeight, view.frame.size.width, view.frame.size.height)]; 
     } 
     else 
     { 
      [view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, fHeight)]; 
      view.backgroundColor = [UIColor blackColor]; 
     } 
    } 
    [UIView commitAnimations]; 
} 



- (void) showTabBar:(UITabBarController *) tabbarcontroller 
{ 
    CGRect screenRect = [[UIScreen mainScreen] bounds]; 
    float fHeight = screenRect.size.height - tabbarcontroller.tabBar.frame.size.height; 

    if( UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)) 
    { 
     fHeight = screenRect.size.width - tabbarcontroller.tabBar.frame.size.height; 
    } 

    [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, fHeight, view.frame.size.width, view.frame.size.height)];    
     } 
     else 
     { 
      [view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, fHeight)]; 
     }  
    } 
    [UIView commitAnimations]; 
} 

también modificó el código para manejar los cambios introducidos en iOS 6 con UIDevice cambio de orientación y asegurarse de que funciona correctamente incluso cuando el dispositivo está tumbado sobre su espalda.

+9

Deberías reemplazar '- 49.0' con' tabbarcontroller.tabBar.frame.size.height' por un código más limpio que tenga menos posibilidades de romperse en futuras versiones de iOS. –

11

Las soluciones de Saurahb y karlbecker_com son geniales, aunque pueden causar un efecto de estallido obvio cuando la vista contiene una tabla de mientras que la barra de pestañas anima una copia de seguridad. Hice algunas modificaciones y las combiné en una sola función (como una categoría en UITabBarController). No es completamente perfecto (animación de corrección retrasada) pero da buenos resultados con las tablas.

Si le gustan los bloques y categorías de animación, pruébelo. Orientación y dispositivo amigable.

UITabBarController + ShowHideBar.m:

#import "UITabBarController+ShowHideBar.h" 

@implementation UITabBarController (ShowHideBar) 

- (void) setHidden:(BOOL)hidden{ 

    CGRect screenRect = [[UIScreen mainScreen] bounds]; 
    float fHeight = screenRect.size.height; 
    if( UIDeviceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation)){ 
     fHeight = screenRect.size.width; 
    } 

    if(!hidden) fHeight -= self.tabBar.frame.size.height; 

    [UIView animateWithDuration:0.25 animations:^{ 
     for(UIView *view in self.view.subviews){ 
      if([view isKindOfClass:[UITabBar class]]){ 
       [view setFrame:CGRectMake(view.frame.origin.x, fHeight, view.frame.size.width, view.frame.size.height)]; 
      }else{ 
       if(hidden) [view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, fHeight)]; 
      } 
     } 
    }completion:^(BOOL finished){ 
     if(!hidden){ 

      [UIView animateWithDuration:0.25 animations:^{ 

       for(UIView *view in self.view.subviews) 
       { 
        if(![view isKindOfClass:[UITabBar class]]) 
         [view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, fHeight)]; 
       } 

      }]; 
     } 
    }]; 

} 

@end 

UITabBarController + ShowHideBar.h:

#import <UIKit/UIKit.h> 

@interface UITabBarController (ShowHideBar) 

- (void) setHidden:(BOOL)hidden; 

@end 

Uso:

[self.tabBarController setHidden:YES]; 
[self.tabBarController setHidden:NO]; 
3

La solución a continuación funciona bien para mí exactamente en el mismo caso de uso donde tengo que pasar al modo de pantalla completa con la animación TabBar.

Básicamente, la idea es

  1. para hacer una instantánea de UITabBar;

  2. añadir el UIImage de la instantánea a UIImageView que tiene el mismo marco que UITabBar hace;

  3. cambiar el tamaño de vista subyacente y lo coloque sobre self.tabBarController.view;

  4. conjunto UITabBar 's alpha to be 0.0;

  5. lugar el UIImageView con instantáneas UITabBar 's en la self.tabBarController.view;

  6. Una vez que se logra lo anterior, hacer cualquier tipo de animación

    #import "QuartzCore/CALayer.h" 
    
    @implementation FTBFirstViewController { 
        BOOL hidden; 
        UIImageView *fakeTabBarImageView; 
        UIView *viewToResize; 
    } 
    
    - (void)viewDidLoad 
    { 
        [super viewDidLoad]; 
    
        ////////////////////////////// 
        // Create your viewToResize 
        ////////////////////////////// 
        [self.view addSubview:viewToResize]; 
    
        hidden = NO; 
    } 
    
    - (void)hideTabBar:(id)sender { 
        if (!hidden) { 
         // 
         // to create the fake UITabBar 
         fakeTabBarImageView = [[UIImageView alloc] initWithFrame:CGRectZero]; 
         UIImage *fakeTabBarImage = [self imageScreenshotFromView:self.tabBarController.tabBar]; 
         fakeTabBarImageView.image = fakeTabBarImage; 
         fakeTabBarImageView.frame = self.tabBarController.tabBar.frame; 
         // 
         // to resize underlying UIView 
         viewToResize.frame = (CGRect){viewToResize.frame.origin.x, viewToResize.frame.origin.y + 20.f, viewToResize.frame.size.width, viewToResize.frame.size.height + fakeTabBarImageView.frame.size.height}; 
         // 
         // to hide real UITabBar 
         self.tabBarController.tabBar.alpha = 0.0; 
         // 
         // to add views in exactly this order 
         [self.tabBarController.view addSubview:viewToResize]; 
         [self.tabBarController.view addSubview:fakeTabBarImageView]; 
         // 
         // do any sort of animation 
         [UIView animateWithDuration:0.8 animations:^{ 
          fakeTabBarImageView.frame = (CGRect){fakeTabBarImageView.frame.origin.x, fakeTabBarImageView.frame.origin.y + fakeTabBarImageView.frame.size.height, fakeTabBarImageView.frame.size}; 
         }]; 
    
         hidden = YES; 
        } else { 
         [UIView animateWithDuration:0.8 animations:^{ 
           fakeTabBarImageView.frame = (CGRect){fakeTabBarImageView.frame.origin.x, fakeTabBarImageView.frame.origin.y - fakeTabBarImageView.frame.size.height, fakeTabBarImageView.frame.size}; 
         } completion:^(BOOL complete){ 
          self.tabBarController.tabBar.alpha = 1.0; 
          [fakeTabBarImageView removeFromSuperview]; 
          fakeTabBarImageView = nil; 
    
          viewToResize.frame = self.view.frame; 
          [self.view addSubview:viewToResize]; 
    
          [fakeTabBarImageView removeFromSuperview]; 
         }]; 
    
         hidden = NO; 
        } 
    } 
    
    - (UIImage *)imageScreenshotFromView:(UIView *)aView { 
        UIImage *viewImage; 
    
        UIGraphicsBeginImageContextWithOptions(aView.bounds.size, aView.opaque, [[UIScreen mainScreen] scale]); 
        [aView.layer renderInContext:UIGraphicsGetCurrentContext()]; 
        viewImage = UIGraphicsGetImageFromCurrentImageContext(); 
        UIGraphicsEndImageContext(); 
    
        return viewImage; 
    } 
    
4

Esta es la respuesta de karlbecker_com, portado a MonoTouch (Xamarin.iOS). La única diferencia es que implementé los métodos en una clase que hereda de UITabBarController, por lo que las referencias a "tabbarcontroller" se reemplazaron por "this".

public void HideTabBar() 
{ 
    var screenRect = UIScreen.MainScreen.Bounds; 
    float fHeight = screenRect.Height; 
    if(UIApplication.SharedApplication.StatusBarOrientation == UIInterfaceOrientation.LandscapeLeft 
     || UIApplication.SharedApplication.StatusBarOrientation == UIInterfaceOrientation.LandscapeRight) 
    { 
     fHeight = screenRect.Width; 
    } 

    UIView.BeginAnimations(null); 
    UIView.SetAnimationDuration(0.4); 
    foreach(UIView view in this.View.Subviews) 
    { 
     if(view is UITabBar) 
     { 
      view.Frame = new RectangleF(view.Frame.X, fHeight, view.Frame.Width, view.Frame.Height); 
     } 
     else 
     { 
      view.Frame = new RectangleF(view.Frame.X, view.Frame.Y, view.Frame.Width, fHeight); 
      view.BackgroundColor = UIColor.Black; 
     } 
    } 
    UIView.CommitAnimations(); 
} 

public void ShowTabBar() 
{ 
    var screenRect = UIScreen.MainScreen.Bounds; 
    float fHeight = screenRect.Height - 49f; 
    if(UIApplication.SharedApplication.StatusBarOrientation == UIInterfaceOrientation.LandscapeLeft 
     || UIApplication.SharedApplication.StatusBarOrientation == UIInterfaceOrientation.LandscapeRight) 
    { 
     fHeight = screenRect.Width - 49f; 
    } 

    UIView.BeginAnimations(null); 
    UIView.SetAnimationDuration(0.4); 
    foreach(UIView view in this.View.Subviews) 
    { 
     if(view is UITabBar) 
     { 
      view.Frame = new RectangleF(view.Frame.X, fHeight, view.Frame.Width, view.Frame.Height); 
     } 
     else 
     { 
      view.Frame = new RectangleF(view.Frame.X, view.Frame.Y, view.Frame.Width, fHeight); 
     } 
    } 
    UIView.CommitAnimations(); 
} 
4

@karlbecker_com respuesta funciona perfecto tanto para el iPhone 4 y el iPhone 5. Si alguien está teniendo problemas con la barra de negro en la parte inferior iOS7 establece la tabBarController a translúcido

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) 

// 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]; 
} 
3

He intentado casi todo estas respuestas, pero ninguna de ellas funcionó para mí. Mi aplicación tiene un UITabBarController como vista raíz, y cada pestaña tiene un UINavigationController. Uno de los UINavigationControllers tiene un UICollectionViewController como el controlador de vista superior. Cuando el usuario selecciona un elemento en UICollectionView, quería que el controlador de vista detallada se insertara en la pila de navegación. Mi vista de detalles tenía una barra de herramientas en la parte inferior. No quería que la barra de herramientas apareciera en la parte superior de la barra de pestañas, ya que eso parece ridículo, y el cambio de contextos de pestañas no será necesario desde esta vista. Probablemente podría haberlo solucionado fácilmente colocando manualmente UIToolbars y UITabbars y sin usar UITabbarController y la UIToolbar incorporada, pero eso parecía demasiado refactorizado y poco elegante.

Al final mi solución fue bastante simple: ampliar los límites del UITabBarController de la parte inferior de la pantalla.He añadido esto a mi equipo de controlador de vista:

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

    // Extend the UITabBarController to shift the tab bar off screen 
    CGRect screenRect = [[UIScreen mainScreen] bounds]; 
    CGRect tabBarControllerFrame = self.tabBarController.view.frame; 
    if (animated) { 
     [UIView beginAnimations:nil context:NULL]; 
     [UIView setAnimationDuration:0.5]; 
     tabBarControllerFrame.size.height = screenRect.size.height + 
      self.tabBarController.tabBar.frame.size.height; 
     [self.tabBarController.view setFrame:tabBarControllerFrame]; 
     [UIView commitAnimations]; 
    } 
    else { 
     tabBarControllerFrame.size.height = screenRect.size.height + 
      self.tabBarController.tabBar.frame.size.height; 
     [self.tabBarController.view setFrame:tabBarControllerFrame]; 
    } 

    // Now show the toolbar 
    [self.navigationController setToolbarHidden:NO animated:animated]; 
} 

- (void)viewWillLayoutSubviews 
{ 
    [super viewWillLayoutSubviews]; 

    // Ensure the UITabBarController remains extended when subviews are laid out 
    CGRect screenRect = [[UIScreen mainScreen] bounds]; 
    CGRect tabBarControllerFrame = self.tabBarController.view.frame; 
    tabBarControllerFrame.size.height = screenRect.size.height + 
     self.tabBarController.tabBar.frame.size.height; 
    [self.tabBarController.view setFrame:tabBarControllerFrame]; 
} 

Luego de reshow la barra de pestañas cuando el usuario salga de nuevo a la parte superior de mi UINavigationController, he añadido esto a mi superior controlador de vista:

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

    // Hide toolbar 
    [self.navigationController setToolbarHidden:YES animated:animated]; 

    // Tab bar back on to screen 
    CGRect screenRect = [[UIScreen mainScreen] bounds]; 
    CGRect tabBarControllerFrame = self.tabBarController.view.frame; 
    if (tabBarControllerFrame.size.height != screenRect.size.height) { 
     if (animated) { 
      [UIView beginAnimations:nil context:NULL]; 
      [UIView setAnimationDuration:0.5]; 
      tabBarControllerFrame.size.height = screenRect.size.height; 
      [self.tabBarController.view setFrame:tabBarControllerFrame]; 
      [UIView commitAnimations]; 
     } 
     else { 
      tabBarControllerFrame.size.height = screenRect.size.height; 
      [self.tabBarController.view setFrame:tabBarControllerFrame]; 
     } 
    } 
} 
3

en iOS8 es suficiente para establecer la propiedad simplemente hidden del tabBar
al igual que en Swift que pueda

rootTabVC = UITabBarController() 
rootTabVC?.tabBar.hidden = true 

Hago esto en mi didFinishLaunchingWithOptions en el appdelegate y funciona bien, creo que si recuerdo correctamente en las versiones anteriores de iOS también necesitaba configurar el frame del tabBar a algo fuera de la pantalla, de lo contrario el tabbar no se mostraría, pero todavía ocupará el espacio.

+0

¿Esto no lo hace invisible? Todavía está allí y obstruirá el hacer clic debajo de él. – h3dkandi

3

Desde IOS 7.1, "Swift" soluciones:

self.tabBarController?.tabBar.hidden = true // hide tabbar 
self.tabBarController?.tabBar.hidden = false // show tabbar 

espero que esto podría ayudar!

+0

Sin embargo, esto no ajusta el espacio de contenido de los controladores de vista. Deja un área libre. – tcurdt

2

Swift y versión modificada del código @Saurabh

Método

func setTabBarHidden (bool:Bool){ 
     for view in tabBarController!.view.subviews { 
      if (view.isKindOfClass(UITabBar)){ 
       let tabBar = view as! UITabBar 
       UIView.animateWithDuration(0.3, animations: {() -> Void in 
        var offset = CGFloat(50) 
        if (bool == false){ 
         offset = -50; 
        } 
        tabBar.frame = CGRect(origin: CGPointMake(tabBar.frame.origin.x, tabBar.frame.origin.y + offset), size: tabBar.frame.size) 
      }) 
     } 
    } 
} 

Para mostrar

override func viewDidLoad() { 
    setTabBarHidden(true) 
} 

Para ocultar

override func viewWillDisappear(animated: Bool) { 
    setTabBarHidden(false) 
} 
1

Aquí hay una adelgazado puerto veloz de la versión @Thomas Verbeek 's para los VCs y sin tablas (probado bajo iOS 8.4):

extension UITabBarController { 

    /** 
    Shows or hides the tabbar 

    :param: hidden   whether to show or hide the tabbar 
    :param: animationDuration the animation's duration 
    */ 
    func setHidden(hidden:Bool, animationDuration:NSTimeInterval = 0.25) { 

     let screenRect = UIScreen.mainScreen().bounds 
     var fHeight = screenRect.size.height 

     if !hidden { 
      fHeight -= self.tabBar.frame.size.height 
     } 

     UIView.animateWithDuration(animationDuration, animations: { 
       for view in self.view.subviews as! [UIView] { 
        if view is UITabBar { 
         view.frame = CGRectMake(
          view.frame.origin.x, 
          fHeight, 
          view.frame.size.width, 
          view.frame.size.height) 
        } 
       } 
      }) 
    } 
} 

Y aquí el puerto más directa (no probado):

extension UITabBarController { 

    /** 
    Shows or hides the tabbar 

    :param: hidden   whether to show or hide the tabbar 
    :param: animationDuration the animation's duration 
    */ 
    func setHidden(hidden:Bool, animationDuration:NSTimeInterval = 0.25) { 

     let screenRect = UIScreen.mainScreen().bounds 
     var fHeight = screenRect.size.height 

     if UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication().statusBarOrientation) { 
      fHeight = screenRect.size.width 
     } 

     if !hidden { 
      fHeight -= self.tabBar.frame.size.height 
     } 

     UIView.animateWithDuration(animationDuration, animations: { 
       for view in self.view.subviews as! [UIView] { 
        if view is UITabBar { 
         view.frame = CGRectMake(
          view.frame.origin.x, 
          fHeight, 
          view.frame.size.width, 
          view.frame.size.height) 
        } 
        else if hidden { 
         view.frame = CGRectMake(
          view.frame.origin.x, 
          view.frame.origin.y, 
          view.frame.size.width, 
          fHeight) 
        } 
       } 
      }, completion: { finished in 
       if !hidden { 
        UIView.animateWithDuration(animationDuration, animations: { 
         for view in self.view.subviews as! [UIView] { 
          if !(view is UITabBar) { 
           view.frame = CGRectMake(
            view.frame.origin.x, 
            view.frame.origin.y, 
            view.frame.size.width, 
            fHeight) 
          } 
         } 
        }) 
       } 
     }) 
    } 
} 
0

Ocultar la barra de pestañas no es una solución adecuada, no ajustará la vista actual de los controladores de vista.

En su lugar, simplemente puede transformar la barra de pestañas, ya sea por su altura (ocultar) o una transformación de identidad para restablecer a visible.

extension UITabBarController { 
    func setBarHiddenAnimated(_ hidden:Bool) { 
     UIView.animate(withDuration: 0.3, animations: { 
      if hidden { 
       self.tabBar.transform = CGAffineTransform(translationX: 0, y: self.tabBar.frame.size.height) 
      } else { 
       self.tabBar.transform = CGAffineTransform.identity 
      } 
     }) 
    } 
} 

Tenga en cuenta que puede que tenga que configurar el controlador de vista a 'se extiende por debajo de las barras inferiores' y 'se extiende por debajo bares opaca' para eliminar el fondo negro durante la animación.

Cuestiones relacionadas