【问题标题】:How to hide uitabbarcontroller如何隐藏uitabbar控制器
【发布时间】:2011-07-13 10:31:27
【问题描述】:

UITabBarController 有问题。在我的应用程序中,我想隐藏它但不使用hidesBottomBarWhenPushed,因为我不想在推送它时隐藏它。例如,我想在我的应用程序中按下隐藏按钮时隐藏它。

我在谷歌上阅读了很多文章,但我不知道如何做到这一点。

【问题讨论】:

标签: iphone ios uitabbarcontroller


【解决方案1】:

我正在从我的工作代码中粘贴它...您可以调用这些方法来隐藏和显示 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]; 
}

【讨论】:

  • 苹果允许你这样做吗?我的意思是,tabbar 应该是只读的.. 只是想知道我的应用程序是否会被拒绝
  • 我正在尝试这个解决方案。当调用 hideTabbar() 方法时,我的标签栏是隐藏的,但它在底部显示黑色空间(定位相同的标签栏)。我该如何解决这个问题?
【解决方案2】:

修改了 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 方向变化的变化,并确保即使设备仰卧也能正常工作。

【讨论】:

  • 您应该将 - 49.0 替换为 tabbarcontroller.tabBar.frame.size.height 以获得更简洁的代码,在未来的 iOS 版本中破坏的可能性更小。
【解决方案3】:

在按钮的操作方法中:

[self.tabBarController.tabBar setHidden:YES];

【讨论】:

  • 这个方法在 iOS 7 中有效,但是在 iOS 6 中它会在标签栏所在的位置留下很大的空隙。
  • 对我来说,在 iOS 13.3 上它不起作用 - 消失了,但留下了空白。
  • 你有没有尝试过视图控制器信息中的“underOpaqueBars”和其他的东西
【解决方案4】:

Saurahb 和 karlbecker_com 的解决方案很棒,尽管当视图包含 tableview 而标签栏动画备份时,它们会导致明显的弹出效果。我做了一些修改并将其组合成一个函数(作为 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];

【讨论】:

    【解决方案5】:

    上面 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

    【讨论】:

      【解决方案6】:

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

      【讨论】:

        【解决方案7】:

        这是 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();
        }
        

        【讨论】:

          【解决方案8】:

          自 IOS 7.1 起,“Swift” 解决方案:

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

          希望这能有所帮助!

          【讨论】:

          • 这不会调整视图控制器的内容空间。留下一个空闲区域。
          【解决方案9】:

          你可以推送一个模态视图控制器

          [self presentModalViewController:myFullscreenViewController animated:YES];
          

          这将在您当前的视图之上创建一个全新的全屏视图。

          使用dismissModalViewController:animated: 关闭ist

          【讨论】:

            【解决方案10】:

            下面的解决方案在我必须使用 TabBar 动画切换到全屏模式的完全相同的用例中对我来说很好。

            基本上,这个想法是

            1. 制作UITabBar的快照;

            2. 将快照的UIImage添加到与UITabBar具有相同帧的UIImageView

              李>
            3. 调整底层视图的大小并将其放置在 self.tabBarController.view;

            4. UITabBar 的 alpha 设置为 0.0;

            5. UIImageViewUITabBar 的快照放在 self.tabBarController.view 上;

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

            【讨论】:

              【解决方案11】:

              我尝试了几乎所有这些答案,但没有一个对我有用。我的应用程序有一个 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];
                      }
                  }
              }
              

              【讨论】:

                【解决方案12】:

                在 iOS8 中,只需设置 tabBarhidden 属性就足够了
                就像在 Swift 中一样,你可以

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

                我在appdelegate 中的didFinishLaunchingWithOptions 中执行此操作,并且效果很好,我想如果我在旧iOS 版本中没记错的话,您还需要将tabBarframe 设置为屏幕,否则tabbar 不会显示,但仍会占用空间。

                【讨论】:

                • 这不是让它不可见吗?它仍然存在并且会阻碍点击它下面的东西。
                【解决方案13】:

                @Saurabh 代码的 Swift 和修改版本

                方法

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

                【讨论】:

                  【解决方案14】:

                  一个带有动画的swift版本,你需要自己设置一个属性isHideTabBar

                  self.isHideTabBar = !self.isHideTabBar
                  UIView.animate(withDuration: 0.5, animations: {
                      self.tabBarController?.tabBar.frame = (self.tabBarController?.tabBar.frame.offsetBy(dx: 0, dy: self.isHideTabBar ? 100 : -100))!
                   })
                  

                  【讨论】:

                    【解决方案15】:

                    已更新并适用于 swift 5 和 ios 14.0

                    /*
                        Shows or hides the tabbar
                    
                        :param: hidden            whether to show or hide the tabbar
                        :param: animationDuration the animation's duration
                    */
                    extension UITabBarController {
                        func setHidden(hidden:Bool, animationDuration:TimeInterval = 0.25) {
                            
                            let screenRect = UIScreen.main.bounds
                            var fHeight = screenRect.size.height
                            
                            if !hidden {
                                fHeight -= self.tabBar.frame.size.height
                            }
                            
                            UIView.animate(withDuration: animationDuration, animations: {
                                for view in self.view.subviews {
                                    if view is UITabBar {
                                        view.frame = CGRect(
                                            x: view.frame.origin.x,
                                            y: fHeight,
                                            width: view.frame.size.width,
                                            height: view.frame.size.height)
                                    }
                                }
                            })
                        }
                    }
                    

                    这是一个更直接的端口(未测试):

                    /*
                        Shows or hides the tabbar
                    
                        :param: hidden            whether to show or hide the tabbar
                        :param: animationDuration the animation's duration
                    */
                    extension UITabBarController {
                        func setHidden(hidden:Bool, animationDuration:TimeInterval = 0.25) {
                            
                            let screenRect = UIScreen.main.bounds
                            var fHeight = screenRect.size.height
                            
                            if UIApplication.shared.statusBarOrientation.isLandscape {
                                fHeight = screenRect.size.width
                            }
                            
                            if !hidden {
                                fHeight -= self.tabBar.frame.size.height
                            }
                            
                            UIView.animate(withDuration: animationDuration, animations: {
                                for view in self.view.subviews {
                                    if view is UITabBar {
                                        view.frame = CGRect(
                                            x: view.frame.origin.x,
                                            y: fHeight,
                                            width: view.frame.size.width,
                                            height: view.frame.size.height)
                                    }
                                    else if hidden {
                                        view.frame = CGRect(
                                            x: view.frame.origin.x,
                                            y: view.frame.origin.y,
                                            width: view.frame.size.width,
                                            height: fHeight)
                                    }
                                }
                            }, completion: { finished in
                                if !hidden {
                                    UIView.animate(withDuration: animationDuration, animations: {
                                        for view in self.view.subviews {
                                            if !(view is UITabBar) {
                                                view.frame = CGRect(
                                                    x: view.frame.origin.x,
                                                    y: view.frame.origin.y,
                                                    width: view.frame.size.width,
                                                    height: fHeight)
                                            }
                                        }
                                    })
                                }
                            })
                        }
                    }
                    

                    【讨论】:

                      【解决方案16】:

                      隐藏标签栏不是一个合适的解决方案,它不会调整当前视图控制器的视图高度。

                      相反,您可以简单地转换标签栏本身,或者通过它的高度(隐藏)或身份转换以重置为可见。

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

                      请注意,您可能需要将视图控制器设置为“在底栏下方延伸”和“在不透明栏下方延伸”以在动画期间移除黑色背景。

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2016-02-22
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2012-08-24
                        相关资源
                        最近更新 更多