ios 如何隐藏uitabbarcontroller
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5272290/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to hide uitabbarcontroller
提问by Viktor Apoyan
I have a problem with UITabBarController
. In my application, I want to hide it but without using hidesBottomBarWhenPushed
because I want to hide it not when I pushed it. For Example, I want to hide it when I press a Hide button in my application.
我有问题UITabBarController
。在我的应用程序中,我想隐藏它但不使用它,hidesBottomBarWhenPushed
因为我不想在推送它时隐藏它。例如,当我按下应用程序中的隐藏按钮时,我想隐藏它。
I read many articles in google but I cant find out how I can do this.
我在谷歌上阅读了很多文章,但我不知道如何做到这一点。
回答by Saurabh
I am pasting this from my working code... you can call these methods to hide and show the tabbarcontroller.... just pass tabbarcontroller instance to these functions..
我正在从我的工作代码中粘贴这个......你可以调用这些方法来隐藏和显示 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];
}
回答by karlbecker_com
Modified Setomidor's answer to work on both landscape, portrait, and iPad (the 320 and 480 values only work on iPhone).
修改了 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];
}
Also modified the code to handle changes introduced in iOS 6 with UIDevice orientation change and ensure that it works properly even when the device is lying on its back.
还修改了代码以处理 iOS 6 中引入的 UIDevice 方向更改,并确保即使设备平躺也能正常工作。
回答by Sailesh
In your action method for the button:
在按钮的操作方法中:
[self.tabBarController.tabBar setHidden:YES];
回答by Thomas Verbeek
Saurahb and karlbecker_com's solutions are great, though they can cause an obvious popping effect when the view contains a tableviewwhile the tab bar animates back up. I've made some modifications and combined it into a single function (as a category on UITabBarController). It's not completely perfect (delayed correction animation) but gives good results with tables.
Saurahb 和 karlbecker_com 的解决方案很棒,尽管当视图包含tableview而标签栏动画备份时,它们会导致明显的弹出效果。我做了一些修改并将它组合成一个单一的函数(作为 UITabBarController 上的一个类别)。它并不完全完美(延迟校正动画),但在表格中给出了很好的结果。
If you like animation blocks and categories, give this a try. Orientation and device friendly.
如果您喜欢动画块和类别,请尝试一下。方向和设备友好。
UITabBarController+ShowHideBar.m:
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:
UITabBarController+ShowHideBar.h:
#import <UIKit/UIKit.h>
@interface UITabBarController (ShowHideBar)
- (void) setHidden:(BOOL)hidden;
@end
Usage:
用法:
[self.tabBarController setHidden:YES];
[self.tabBarController setHidden:NO];
回答by Setomidor
Saurabh's answer above can be extended to also work in landscape orientation:
上面 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];
}
`
`
The corresponding x_pos numbers for showTabBar() are 431
and 271
.
showTabBar() 对应的 x_pos 数字是431
和271
。
回答by Diego
This is karlbecker_com's answer, ported to MonoTouch (Xamarin.iOS).
The only difference is that I implemented the methods on a class that inherits from UITabBarController, so references to "tabbarcontroller
" were replaced by "this
".
这是 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();
}
回答by mikemike396
@karlbecker_com Answer works perfect for both the iPhone 4 and iPhone 5. If anyone is having issues with iOS7 black bar at the bottom set the tabBarController to translucent
@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];
}
回答by Sifeng
Since IOS 7.1, "Swift"solutions:
自 IOS 7.1 起,“Swift”解决方案:
self.tabBarController?.tabBar.hidden = true // hide tabbar
self.tabBarController?.tabBar.hidden = false // show tabbar
Hope this could help!
希望这会有所帮助!
回答by Yevhen Dubinin
The solution below works fine for me in exactly the same use case where I have to move to fullscreen mode with TabBar animation.
在我必须使用 TabBar 动画切换到全屏模式的完全相同的用例中,下面的解决方案对我来说很好用。
Basically, the idea is
基本上,这个想法是
to make a snapshot of UITabBar;
add the UIImageof the snapshot to UIImageViewwhich has the same frame as UITabBardoes;
resize underlying view and place it on self.tabBarController.view;
set UITabBar's alpha to be 0.0;
place the UIImageViewwith UITabBar's snapshot on the self.tabBarController.view;
Once the above is achieved, do any kind of animation
#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; }
制作UITabBar的快照;
将快照的UIImage添加到与UITabBar具有相同框架的UIImageView中;
调整底层视图的大小并将其放在self.tabBarController.view 上;
将UITabBar的 alpha 设置为 0.0;
将带有UITabBar快照的UIImageView放在self.tabBarController.view 上;
完成上述操作后,执行任何类型的动画
#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; }
回答by SeanR
I tried pretty much all these answers but none of them worked for me. My app has a UITabBarController as the root view, and each tab has a UINavigationController. One of the UINavigationControllers has a UICollectionViewController as the top view controller. When the user selects an item in the UICollectionView, I wanted the detail view controller to get pushed onto the navigation stack. My detail view then had a toolbar at the bottom. I didn't want the toolbar to appear on top of the tab bar as that looks goofy, and switching tab contexts won't be needed from this view. I could probably have easily solved this by manually placing UIToolbars and UITabBars and not using UITabBarController and the built-in UIToolbar, but that seemed like too much refactoring and a bit inelegant.
我几乎尝试了所有这些答案,但没有一个对我有用。我的应用程序有一个 UITabBarController 作为根视图,每个选项卡都有一个 UINavigationController。其中一个 UINavigationControllers 有一个 UICollectionViewController 作为顶视图控制器。当用户在 UICollectionView 中选择一个项目时,我希望细节视图控制器被推送到导航堆栈上。我的详细信息视图底部有一个工具栏。我不希望工具栏出现在选项卡栏的顶部,因为这看起来很傻,并且不需要从此视图切换选项卡上下文。我可以通过手动放置 UIToolbars 和 UITabBars 而不是使用 UITabBarController 和内置的 UIToolbar 来轻松解决这个问题,但这似乎重构太多,有点不优雅。
In the end my solution was fairly simple: extend the bounds of the UITabBarController off the bottom of the screen. I added this to my detail view controller:
最后,我的解决方案相当简单:将 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];
}
Then to reshow the tab bar when the user pops back to the top of my UINavigationController, I added this to my top view controller:
然后当用户弹回到我的 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];
}
}
}