2011-03-11 100 views
72

我與UITabBarController有問題。在我的應用程序中,我想隱藏它,但不使用hidesBottomBarWhenPushed,因爲我不想在隱藏時將其隱藏。例如,當我在應用程序中按隱藏按鈕時,我想隱藏它。如何隱藏uitabbarcontroller

我在谷歌閱讀了很多文章,但我不知道我該如何做到這一點。

+0

可能重複的[Iphone:是否可以隱藏TabBar?](http://stackoverflow.com/questions/1982172/iphone-is-it-possible-to-hide-the-tabbar) – Pang 2014-03-18 09:14:46

回答

149

我從我工作的代碼粘貼此...你可以調用這些方法來隱藏和顯示tabbarcontroller ....只是通過tabbarcontroller實例,這些功能..

// 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

蘋果允許你這樣做嗎?我的意思是,tabbar應該只讀..只是想知道我的應用程序是否會被拒絕 – mateusmaso 2012-02-19 05:14:36

+3

我正在嘗試這個解決方案。當調用hideTabbar()方法我的標籤欄是隱藏的,但它顯示底部的黑色空間(位置相同的標籤欄)。我如何解決這個問題? – Thunderbird 2014-08-20 05:31:01

32

在該按鈕的操作方法:

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

此方法適用於iOS 7,但在iOS 6中,它會在標籤欄處留下很大的空白。 – 2013-11-05 16:36:10

3

,你可以把一個模式視圖控制器

[self presentModalViewController:myFullscreenViewController animated:YES]; 

這將創建上述當前的一個全新的全屏觀看。

解僱IST與dismissModalViewController:animated:

9

SAURABH的回答上面可以擴展到在橫向也行:

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

`

爲showTabBar()對應的X_POS號碼431271

58

修改後的Setomidor可以在橫向,縱向和iPad上工作(320和480值僅適用於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]; 
} 

還修改了代碼來處理在iOS 6中使用的UIDevice方向變化帶來的變化,並確保其正常工作,甚至當設備仰臥。

+9

您應該用'tabbarcontroller.tabBar.frame.size.height'替換' - 49.0',以獲得更清晰的代碼,這樣在未來的iOS版本中破壞的機會就越小。 – 2013-06-15 20:02:54

11

Saurahb和karlbecker_com的解決方案非常棒,但當視圖包含桌面視圖而標籤欄動畫備份時,它們可能會引起明顯的彈出效果。我做了一些修改,並將其組合成一個單一的功能(作爲UITabBarController的一個類別)。這不完全完美(延遲校正動畫),但表格帶來了不錯的效果。

如果您喜歡動畫塊和類別,請嘗試一下。方向和設備友好。

的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 

用法:

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

下面的解決方案工作正常,我完全一樣的使用情況下我必須移動到與動畫的TabBar全屏模式。

基本上,這個想法是

  1. 使UITabBar的快照;

  2. 添加的UIImage快照到的UIImageView其具有相同的幀中UITabBar確實;

  3. 調整底層視圖的大小並將其放置在self.tabBarController.view;

  4. set UITabBar的alpha爲0.0;

  5. 代替的UIImageView與上self.tabBarController.viewUITabBar的快照;

  6. 一旦上述得以實現,做動畫

    的任何一種
    #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

這是karlbecker_com的回答,移植到MonoTouch的(Xamarin.iOS)。 唯一的區別是我在繼承自UITabBarController的類上實現了方法,因此對「tabbarcontroller」的引用被替換爲「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答作品完美無論是iPhone 4和iPhone 5,如果有人有在底部iOS7黑條問題設置tabBarController半透明

#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

我幾乎嘗試了所有多這些答案,但他們都沒有爲我工作。我的應用程序有一個UITabBarController作爲根視圖,每個選項卡都有一個UINavigationController。其中一個UINavigationControllers具有UICollectionViewController作爲頂部視圖控制器。當用戶在UICollectionView中選擇一個項目時,我希望細節視圖控制器被推到導航堆棧上。我的詳細視圖然後在底部有一個工具欄。我不希望工具欄出現在標籤欄頂部,因爲看起來很愚蠢,並且從該視圖切換標籤上下文將不需要。我可能很容易通過手動放置UIToolbars和UITabBars而不是使用UITabBarController和內置的UIToolbar來解決這個問題,但是這看起來像是太多的重構,而且有點不雅。

最後,我的解決方案非常簡單:將UITabBarController的界限從屏幕底部延伸出來。我將此添加到我的詳細視圖控制器:

- (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]; 
} 

當用戶彈出回到我的UINavigationController的頂部然後重新顯示標籤欄,我已將此添加到我的頂視圖控制器:

- (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

在iOS8上是不夠的,只是設置tabBar
一樣的hidden財產斯威夫特可以

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

我在我的didFinishLaunchingWithOptionsappdelegate中這樣做,它工作正常,我認爲如果我沒有記錯在舊的iOS版本中,您還需要將tabBarframe設置爲屏幕外的內容,否則tabbar不會顯示,但它會顯示仍然會佔據這個空間。

+0

這不就是讓它看不見嗎?它仍然存在,並會阻止點擊它下面的東西。 – h3dkandi 2016-06-23 07:28:19

3

由於IOS 7.1,「雨燕」解決方案:

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

希望這可以幫助!

+0

雖然這不會調整視圖控制器的內容空間。留下一個自由區域。 – tcurdt 2016-08-21 18:14:39

2

斯威夫特和@Saurabh代碼修改版本

方法

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) 
      }) 
     } 
    } 
} 

要顯示

override func viewDidLoad() { 
    setTabBarHidden(true) 
} 

要隱藏

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

這裏是@Thomas維貝克的版本,對於那些風險投資商一個精簡下來迅速端口,而不表(的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) 
        } 
       } 
      }) 
    } 
} 

而這裏更直接的端口(未測試):

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

隱藏標籤欄並不是一個適當的解決方案,它不會調整當前的視圖控制器視圖高度。

相反,您可以簡單地轉換標籤欄本身,或者通過它的高度(隱藏)或身份轉換重置爲可見。

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 
      } 
     }) 
    } 
} 

請注意,您可能需要您的視圖控制器設置爲「下面伸出底杆」和「下不透明條延伸」動畫過程中去除黑色的背景。