推送 UIView 时隐藏 UITabBar

Posted

技术标签:

【中文标题】推送 UIView 时隐藏 UITabBar【英文标题】:Hiding UITabBar when pushing a UIView 【发布时间】:2010-10-15 02:57:12 【问题描述】:

我有一个UITabBarController,其中默认视图控制器是UINavigationController。当我在UINavigationController 中推送某个视图时,我希望能够隐藏 UITabBarController 的 UITabBar。

我已经尝试添加:

delegate.tabBarController.hidesBottomBarWhenPushed = YES;

在我推送视图之前,在我的UINavigationController 中,但这似乎不起作用。

关于我应该做什么或者是否有可能的任何提示?提前致谢!

【问题讨论】:

【参考方案1】:

事实证明,如果您将视图设置为hidesBottomBarWhenPushed:YES,它会在视图出现时隐藏栏(对我而言,呵呵)。我把它分配给了UITabBarController,仔细想想,这并没有多大意义。

[self.view hidesBottomBarWhenPushed:YES];
[super pushViewController:viewController animated:animated];

【讨论】:

错了。这两种方法都应该应用于你要推入的视图控制器。【参考方案2】:

这样更好:

viewController.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:viewController animated:YES];

您必须在要推送到视图中的控制器上设置 hidesBottomBarWhenPushed = YES...

【讨论】:

这肯定更好。谢谢! 要记住的一件事:您必须在将上面的代码推送到控制器之前将其放入。那是在初始化行之后。如果你把它放在 viewDidLoad 或类似的地方,它就行不通了...... 非常感谢。我希望 Apple 将此添加到文档中,我很困惑。 我在标签栏上方使用相同的代码被隐藏,但我的底部栏看起来像是从上到下的动画。【参考方案3】:

这是你如何让它工作的:

Application Delegate 中创建UITabBarController。然后你创建一个UINavigationController,它的根控制器作为你想要在特定选项卡中的视图控制器。然后将UINavigationController 插入UITabBarController 的“viewControllers”数组中。像这样:

ViewControllerForTab1 *tab1Controller = [[ViewControllerForTab1 alloc] initWithNibName:@"ViewControllerForTab1"];

UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:tab1Controller];

[tab1Controller release];


UITabBarController *tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = [NSArray arrayWithObjects: navController, nil];

[navController release];


[self.window addSubView:tabBarController.view];

这样,您可以在UINavigationController 内的任何视图控制器中将“hidesBottomBarWhenPushed”属性设置为“YES”,它将隐藏UITabBar

希望有帮助!

【讨论】:

【参考方案4】:

我会在这里给出我的解决方案:

#define FRAME_HIDDEN CGRectMake(0, 0, 768, 1073) //1073 = 1024 (screen) + 49 (UITabBar) 
#define FRAME_APPEAR CGRectMake(0, 0, 768,1024)

-(void) setHidden: (BOOL) hidden
    CGRect frame = (hidden)? FRAME_HIDDEN : FRAME_APPEAR;
    [self.tabBarController.view setFrame:frame];
    [self.tabBarController.tabBar setHidden:hidden];

在需要的地方调用“setHidden”方法!我使用这个和“单例模式”,然后我的子视图可以在他的 Superview 中隐藏 UITabBar

【讨论】:

这样隐藏是行不通的。好吧,它确实有效,但它在标签栏曾经所在的位置留下了一些黑色背景,从我的角度来看,这是无法访问的。将标签栏移到屏幕的可见部分之外就可以了。但是,这确实会影响屏幕的边界,这可能会对应用的其他部分产生副作用。 对不起,上面的评论有误,我不能再编辑了。与使用 hidesBottomBarWhenPushed 的(对我来说不够)解决方案相比,显然更改 tabBarController 的视图框架确实对子视图的布局产生了一些影响。我仍在调查,可能会在此处发布更新,除非错误出现在我的计算中。 嗯,我确实观察到了一些可能感兴趣的副作用:我确实在全屏最底部的视图中放置了一个小的子视图。假设没有标签栏,因此使用标签栏通常占用的空间。我在 IB 中添加了这个子视图。在 IB 中,您将每个视图缝合到一个或多个边缘或屏幕/子视图的中心以实现自动调整大小。这种自动化的方向变化。但是,它确实将我的子视图与标签栏一起重新定位到屏幕下方的某个位置。请记住自动调整大小。 为混乱道歉。在我最终得到它之前,我不应该发表评论。我将添加我的解决方案作为单独的答案。我的解决方案基于您的解决方案,但已扩展为支持各种方向以及推动标签栏应重新出现的详细视图控制器。【参考方案5】:

我已经弄清楚如何解决这个问题,我遇到了同样的问题,但 Apple 还在名为“The Elements”的示例中告诉我们如何解决这个问题 (http://developer.apple.com/library/ios/#samplecode/TheElements/Introduction/Intro.html)

请参阅下面的函数以了解如何执行此操作,将此添加到要推送的视图的 init 函数中!

-(id) init  
    if(self = [super init])  
        self.hidesBottomBarWhenPushed = YES; 
     
    return self; 

它会自动隐藏标签栏,就像 iPhone 上的照片应用一样。当您返回时,父视图将再次显示标签栏。

祝你好运

【讨论】:

这对我很有用。比目前任何其他解决方案都好【参考方案6】:

我已经尝试了大多数建议的解决方案。最后,他们都没有为我工作。

hideTabBarWhenPushed 不仅为下一个推送的视图控制器隐藏标签栏,还为所有推送到其中的视图控制器隐藏标签栏。对于那些我确实希望标签栏控制器重新出现的人。

Orafaelreis 的解决方案(见上文)似乎最适合这一点。但他的尝试只适用于严格的纵向,甚至不适用于倒置。所以我不得不修补它。这就是我最终得到的:

#define kTabBarHeight               49 // This may be different on retina screens. Frankly, I have not yet tried.

- (void) hideTabBar:(BOOL)hide 

    // fetch the app delegate
    AppDelegate         *delegate   = [[UIApplication sharedApplication] delegate];

    // get the device coordinates
    CGRect              bounds      = [UIScreen mainScreen].bounds;
    float               width;
    float               height;

    // Apparently the tab bar controller's view works with device coordinates  
    // and not with normal view/sub view coordinates
    // Therefore the following statement works for all orientations. 
    width                   = bounds.size.width;
    height                  = bounds.size.height;

    if (hide) 

        // The tab bar should be hidden too. 
        // Otherwise it may flickr up a moment upon rotation or 
        // upon return from detail view controllers. 
        [self.tabBarController.tabBar setHidden:YES];

        // Hiding alone is not sufficient. Hiding alone would leave us with an unusable black
        // bar on the bottom of the size of the tab bar. 
        // We need to enlarge the tab bar controller's view by the height of the tab bar. 
        // Doing so the tab bar, although hidden, appears just beneath the screen. 
        // As the tab bar controller's view works in device coordinations, we need to enlarge 
        // it by the tab bar height in the appropriate direction (height in portrait and width in landscape)
        // and in reverse/upside down orientation we need to shift the area's origin beyond zero. 
        switch (delegate.tabBarController.interfaceOrientation) 
            case UIInterfaceOrientationPortrait:
                // Easy going. Just add the space on the bottom.
                [self.tabBarController.view setFrame:CGRectMake(0,0,width,height+kTabBarHeight)];
                break;

            case UIInterfaceOrientationPortraitUpsideDown:
                // The bottom is now up! Add the appropriate space and shift the rect's origin to y = -49
                [self.tabBarController.view setFrame:CGRectMake(0,-kTabBarHeight,width,height+kTabBarHeight)];
                break;

            case UIInterfaceOrientationLandscapeLeft:
                // Same as Portrait but add the space to the with but the height
                [self.tabBarController.view setFrame:CGRectMake(0,0,width+kTabBarHeight,height)];
                break;

            case UIInterfaceOrientationLandscapeRight:
                // Similar to Upside Down: Add the space and shift the rect. Just use x and with this time
                [self.tabBarController.view setFrame:CGRectMake(0-kTabBarHeight,0,width+kTabBarHeight,height)];
                break;

            default:
                break;
        
     else 
        // reset everything to its original state. 
        [self.tabBarController.view setFrame:CGRectMake(0,0,width,height)];
        [self.tabBarController.tabBar setHidden:NO];
    

    return; 



- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation

    // It is important to call this method at all and to call it here and not in willRotateToInterfaceOrientation
    // Otherwise the tab bar will re-appear. 
    [self hideTabBar:YES];

    // You may want to re-arrange any other views according to the new orientation
    // You could, of course, utilize willRotateToInterfaceOrientation instead for your subViews. 


- (void)viewWillAppear: (BOOL)animated  

    // In my app I want to hide the status bar and navigation bar too. 
    // You may not want to do that. If so then skip the next two lines. 
    self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
    [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];

    [self hideTabBar: YES];

    // You may want to re-arrange your subviews here. 
    // Orientation may have changed while detail view controllers were visible. 
    // This method is called upon return from pushed and pulled view controllers.   

    return;


- (void)viewWillDisappear: (BOOL)animated      

    // This method is called while this view controller is pulled
    // or when a sub view controller is pushed and becomes visible
    // Therefore the original settings for the tab bar, navigation bar and status bar need to be re-instated

    [self hideTabBar:NO];

    // If you did not change the appearance of the navigation and status bar in viewWillAppear,
    // then you can skip the next two statements too. 
    self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
    [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];

    return;

内嵌 cmets 应解释每个语句的推理。不过,可能有更聪明的编码方式。

隐藏状态栏和导航栏也有一个副作用,我不想对你们隐藏。 1. 当从这个导航控制器返回到调用导航控制器时,调用控制器上的状态栏和导航栏会重叠,直到设备旋转一次或直到另一个选项卡出现后再次选择相关选项卡。 2. 当调用视图控制器是一个表格视图并且当设备在返回表格时处于横向模式时,表格以适合横向的方向显示,但它的布局就像它是纵向的一样。左上角很好,但一些表格单元格和标签栏隐藏在屏幕下方。右侧有一些空闲空间。这也可以通过再次旋转设备来解决。

一旦找到这些小但令人讨厌的错误的解决方案,我会及时通知您。

【讨论】:

【参考方案7】:

在使用情节提要时,它易于设置视图控制器,它将在推送时隐藏标签栏,在目标视图控制器上只需选中此复选框:

【讨论】:

【参考方案8】:

在第一个 UIViewController FirstItemViewController

@IBAction func pushToControllerAction(sender: AnyObject) 
  self.hidesBottomBarWhenPushed = true
  self.performSegueWithIdentifier("nextController", sender: self)

在下一个 UIViewController ExampleViewController

override func willMoveToParentViewController(parent: UIViewController?) 
  if parent == nil 
    var viewControllers = self.navigationController!.viewControllers
    if ((viewControllers[viewControllers.count - 2]).isKindOfClass(FirstItemViewController.self)) 
      (viewControllers[viewControllers.count - 2] as! FirstItemViewController).hidesBottomBarWhenPushed = false
    
  

看这个答案https://***.com/a/36148064/3078925

【讨论】:

【参考方案9】:

在要隐藏的控制器中使用hidesBottomBarWhenPushed

用于隐藏所有放入prepare for segue的控制器

override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
    segue.destination.hidesBottomBarWhenPushed = true

【讨论】:

以上是关于推送 UIView 时隐藏 UITabBar的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 中向 UIView 添加第二个 UITabBar(控制器?)

当 UIView 被隐藏时会发生啥?

如何在滚动时隐藏 UIView?

当调整大小小于元素时,如何使元素隐藏在 UIView 中

UIView 越界时隐藏子视图

如何在更改uiview的隐藏模式时添加动画?