Iphone:是不是可以隐藏 TabBar? (iOS 8 之前的版本)

Posted

技术标签:

【中文标题】Iphone:是不是可以隐藏 TabBar? (iOS 8 之前的版本)【英文标题】:Iphone: Is it possible to hide the TabBar? (Pre-iOS 8)Iphone:是否可以隐藏 TabBar? (iOS 8 之前的版本) 【发布时间】:2009-12-30 20:06:33 【问题描述】:

我有一个使用UITabBarController 在模式之间切换的应用程序。在某种模式下,我想隐藏标签栏,直到该模式的步骤完成。请注意,我没有使用导航控制器,所以我不能使用导航控制器上的setHidesBottomBarWhenPushed 方法来隐藏标签栏。

ios 8 之前,当我尝试使用以下方式隐藏 tarbar 时:

self.tabBarController.tabBar.hidden = YES

标签栏消失了,但它在屏幕底部留下了一个 50 像素的空白区域,该区域曾经是标签栏。我似乎无法弄清楚如何填充该区域。该区域中的 UI 中的任何内容都会被剪裁,无法看到。

如果这是可能的,有什么想法吗?我真的很想远离导航控制器。

【问题讨论】:

似乎获得我想要的视觉行为的一件事是简单地将 TabBarController 的框架更改为 (0,0,320,530)。这会将标签栏推离显示器底部,并允许使用全屏。不完全是一个完美的解决方案,但它似乎可以工作,直到出现更好的东西。 感谢您的想法。这很丑陋,但可以解决问题。 嗨,我如何在以后的屏幕中恢复 tabBar? @quantumpotato 只需将帧边界重置回 (0,0,320,480) 即可将标签栏向上移动。 请注意,在 iOS 8 中,这个 .tabBar.hidden = true 可以正常工作,死/空白屏幕区域完全没有问题。 【参考方案1】:

这是我的代码:

当然,这与控制器视图层次结构中的正在发生的事情混为一谈。它可能会改变/中断。这使用已定义的 API,因此 Apple 不会关心,但他们也不会关心破坏您的代码。

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

编辑: 一位匿名用户建议在 7.0 中添加以下内容(我没有对此进行测试,也不能说它是一种解决方法还是一种理想的实现方式):

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

编辑:在 8.x 中完全未经测试,并且可能缺少某些布局。

【讨论】:

这太棒了!我们完成此操作的旧方法导致标签栏曾经所在的屏幕部分无响应,但此方法不会。如果您同时隐藏导航栏,我建议将动画持续时间更改为 UINavigationControllerHideShowBarDuration 其实这个方法会导致我的子视图的框架出现问题,所以我不得不改用hidesBottomBarWhenPushed属性。 也许改变视图的大小调整行为会导致问题不会发生?很难说,不知道实际问题是什么。 这是一项了不起的工作! bshirley先生 它会导致其他子视图出现问题。【参考方案2】:

像史蒂夫一样,我还没有找到一种干净的方法来做到这一点(即使 Apple Photopicker 做了类似的事情)。这是我所做的:

 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;
  

它所做的是将视图向下推,以便我可以显示工具栏(而不是隐藏它)。显然,这仅适用于标签栏 + 导航控制器的“根视图”。对于任何后续视图,您可以在要推送的视图控制器上设置“hidesBottomBarWhenPushed”。

【讨论】:

【参考方案3】:

我尝试了上面的一些解决方案,但在 iOS 8 中没有任何乐趣。我发现 viewWillAppear 中的设置对我有用。应该在 iOS 7 中工作,因为当时引入了 extendedLayoutIncludesOpaqueBars。

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

如果您需要在离开时再次打开 tabBars 以在 viewWillDisappear 中使用以下内容。

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

我使用它来允许从转换返回以保持 TabBar 隐藏。没有在按钮操作中使用它,但如果你像我一样发现上面没有任何效果,这可能是可编程解决方案的基础。

【讨论】:

【参考方案4】:

今天有点晚了,但在我今天下午浏览的所有问题的答案中,这是最适合我的一个。

How to hide 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]; 

【讨论】:

代码中的魔法常数!非常糟糕的例子,尤其是在 iPhone 6(+) 发布之后。 [[UIScreen mainScreen] bounds] 设置合适的大小要好得多。【参考方案5】:

我只使用这一行来实现这一点。在显示具有标签栏的视图控制器之前,我使用 prepareForSegue 方法。

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

【讨论】:

太好了,正是我需要的:-)【参考方案6】:

我处理过几乎相同的案例,实际上使用了来自http://www.developers-life.com/hide-uitabbarcontrolleruitabbar-with-animation.html 的代码,并根据我的需要对其进行了改进,这也可能对其他人有所帮助。

我使用 UISplitViewController 作为根视图控制器,它的细节部分是一个 UITabBarController,我不得不在纵向模式下隐藏标签栏:

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

我使用下面的代码来调用 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;

我测试了这段代码只能在模拟器中运行,如果它也可以在设备上运行,请告诉我 ;-)

【讨论】:

【参考方案7】:

你在子视图上设置了 autoResizingMask 吗?

view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

类似的东西应该可以解决问题,并允许位于堆栈顶部的视图重新调整大小。

【讨论】:

刚刚试过。没有效果。我仍然在屏幕底部看到一个 50 像素的空白区域【参考方案8】:

保留原始架构的明显解决方案是以模态方式呈现该视图:

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

视图现在覆盖了包括标签栏在内的整个屏幕(状态栏除外),因此看起来标签栏已经消失以响应用户按下该标签栏项目。

【讨论】:

【参考方案9】:

自动调整大小的掩码有一个枚举。尝试设置所有选项并检查是否在父视图中选中了 autoresize subviews 选项

【讨论】:

【参考方案10】:

您可以轻松创建标签栏类别并显示/隐藏。并且您可以访问完整视图。

创建类别#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

注意:当 hotspotcall 为 ON 时使用 statusbarFrame,因此标签栏不会被切断。

现在导入你想要使用方法的类,然后调用下面的方法来隐藏或显示标签栏。

[self.tabBarController hideTabBarAnimated:YES];

[self.tabBarController showTabBarAnimated:YES];

希望对您有所帮助。

【讨论】:

【参考方案11】:

希望这行得通。

@interface UITabBarController(添加) -(void)setTabBarHidden:(BOOL)隐藏动画:(BOOL)动画; @结尾 @implementation UITabBarController(添加) -(void)setTabBarHidden:(BOOL)隐藏动画:(BOOL)动画 如果(动画) [UIView beginAnimations:nil context:nil]; 如果(隐藏) self.tabBar.frame = CGRectMake(self.tabBar.frame.origin.x, self.tabBar.superview.frame.size.height, self.tabBar.bounds.size.width, self.tabBar.bounds.size.height) ; 别的 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.宽度,self.tabBar.bounds.size.height); 如果(动画) [UIView 提交动画];

【讨论】:

【参考方案12】:

这是我的解决方案(我的选项卡视图控制器位于导航控制器内部,以便更好地衡量)...所以我将 UITabBarController 子类化并这样做了...公开-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];
    ];

【讨论】:

【参考方案13】:

将语句放在UIViewController的init方法中

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

【讨论】:

【参考方案14】:

看到这个帖子:

Show/Hide TabBarController in iphone

总之,您可以在此示例代码中看到此行为的示例:

http://developer.apple.com/iphone/library/samplecode/TheElements/index.html

【讨论】:

不幸的是,这需要使用导航控制器来在推送新的视图控制器时隐藏标签栏。我没有使用导航控制器,所以这对我不起作用。【参考方案15】:

你为什么不使用导航控制器。隐藏导航栏比隐藏标签栏要容易得多...

【讨论】:

我对这个项目的演示版本有一个相当紧迫的截止日期,我宁愿不必后退一步来完成它。一旦演示版问世,资金涌入门内 :-) 我很可能会完全重写 UI 并使用导航控制器。【参考方案16】:

刚刚在 UITabBarController 的子类中的 Monotouch 中编写了以下代码:

    public void ShowTabBar()
    
        UIView.BeginAnimations("Anim");
        UIView.SetAnimationDuration(0.25f);
        this.View.Subviews[0].Frame = new RectangleF(0f, 0f, 320f, 431f);
        this.TabBar.Frame = new RectangleF(0f, 431f, 320f, 49f);
        this.TabBar.Hidden = false;
        UIView.CommitAnimations();
    

    public void HideTabBar()
    
        UIView.BeginAnimations("Anim");
        UIView.SetAnimationDuration(0.25f);
        this.View.Subviews[0].Frame = new RectangleF(0f, 0f, 320f, 480f);
        this.TabBar.Frame = new RectangleF(0f, 481f, 320f, 510f);
        this.TabBar.Hidden = true;
        UIView.CommitAnimations();          
    

【讨论】:

以上是关于Iphone:是不是可以隐藏 TabBar? (iOS 8 之前的版本)的主要内容,如果未能解决你的问题,请参考以下文章

TabBar 隐藏起来,无论我怎么问都不想回来......

iOS-导航栏、状态栏及Tabbar高度(区分iPhone X与其他iPhone机型)

在 iPhone 上隐藏 UITabBar 时显示黑条

iOS 7 - 隐藏 tabBar 并显示 toolBar

在 iPhone 上更改 Tabbar 的颜色

iOS进入界面隐藏下方tabbar等bar