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
注意:当 hotspot 或 call 为 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 之前的版本)的主要内容,如果未能解决你的问题,请参考以下文章