如何隐藏uitabbarcontroller

发布于 2024-10-21 04:00:05 字数 169 浏览 1 评论 0原文

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

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

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.

I read many articles in google but I cant find out how I can do this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(16

如若梦似彩虹 2024-10-28 04:00:05

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

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

// 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]; 
}
佞臣 2024-10-28 04:00:05

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

Modified Setomidor's answer to work on both landscape, portrait, and iPad (the 320 and 480 values only work on 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.

刘备忘录 2024-10-28 04:00:05

在按钮的操作方法中:

[self.tabBarController.tabBar setHidden:YES];

In your action method for the button:

[self.tabBarController.tabBar setHidden:YES];
美煞众生 2024-10-28 04:00:05

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

Saurahb and karlbecker_com's solutions are great, though they can cause an obvious popping effect when the view contains a tableview while 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.

If you like animation blocks and categories, give this a try. Orientation and device friendly.

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

Usage:

[self.tabBarController setHidden:YES];
[self.tabBarController setHidden:NO];
谎言 2024-10-28 04:00:05

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

Saurabh's answer above can be extended to also work in landscape orientation:

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

无语# 2024-10-28 04:00:05

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

@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

#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];
}  
心舞飞扬 2024-10-28 04:00:05

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

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".

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();
}
故笙诉离歌 2024-10-28 04:00:05

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

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

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

in iOS8 it is enough to just set the hidden property of the tabBar
Like in Swift you can

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

I do this in my didFinishLaunchingWithOptions in the appdelegate and it works fine, I think if I remember correctly in the older iOS versions you also needed to set the frame of the tabBar to something outside the screen, otherwise the tabbar would not show but it will still occupy the space.

遇见了你 2024-10-28 04:00:05

从 IOS 7.1 开始,“Swift” 解决方案:

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

希望这能有所帮助!

Since IOS 7.1, "Swift" solutions:

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

Hope this could help!

不及他 2024-10-28 04:00:05

您可以推送模式视图控制器,

[self presentModalViewController:myFullscreenViewController animated:YES];

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

使用 dismissModalViewController:animated: 关闭 ist

you can push a modal view controller

[self presentModalViewController:myFullscreenViewController animated:YES];

this will create a completely new view fullscreen above your current one.

dismiss ist with dismissModalViewController:animated:

情归归情 2024-10-28 04:00:05

在完全相同的用例中,下面的解决方案对我来说效果很好,我必须使用 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"
    
    @实现FTBFirstViewController {
       BOOL 隐藏;
       UIImageView *fakeTabBarImageView;
       UIView *viewToResize;
    }
    
    - (void)viewDidLoad
    {
        [超级viewDidLoad];
    
        //////////////////////////////////////////////////////////
        // 创建你的viewToResize
        //////////////////////////////////////////////////////////
        [self.view addSubview:viewToResize];
    
        隐藏=否;
    }
    
    - (void)hideTabBar:(id)sender {
        如果(!隐藏){
            //
            // 创建假的 UITabBar
            fakeTabBarImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
            UIImage *fakeTabBarImage = [self imageScreenshotFromView:self.tabBarController.tabBar];
            fakeTabBarImageView.image = fakeTabBarImage;
            fakeTabBarImageView.frame = self.tabBarController.tabBar.frame;
            //
            // 调整底层 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。高度};
            //
            // 隐藏真实的 UITabBar
            self.tabBarController.tabBar.alpha = 0.0;
            //
            // 严格按照这个顺序添加视图
            [self.tabBarController.view addSubview:viewToResize];
            [self.tabBarController.view addSubview:fakeTabBarImageView];
            //
            // 做任何类型的动画
            [UIView animateWithDuration:0.8 动画:^{
                fakeTabBarImageView.frame = (CGRect){fakeTabBarImageView.frame.origin.x, fakeTabBarImageView.frame.origin.y + fakeTabBarImageView.frame.size.height, fakeTabBarImageView.frame.size};
            }];
    
            隐藏=是;
        } 别的 {
            [UIView animateWithDuration:0.8 动画:^{
                    fakeTabBarImageView.frame = (CGRect){fakeTabBarImageView.frame.origin.x, fakeTabBarImageView.frame.origin.y - fakeTabBarImageView.frame.size.height, fakeTabBarImageView.frame.size};
            } 完成:^(BOOL 完成){
                self.tabBarController.tabBar.alpha = 1.0;
                [fakeTabBarImageView removeFromSuperview];
                fakeTabBarImageView = nil;
    
                viewToResize.frame = self.view.frame;
                [self.view addSubview:viewToResize];
    
                [fakeTabBarImageView removeFromSuperview];
            }]; 
    
            隐藏=否;
        }
    }
    
    - (UIImage *)imageScreenshotFromView:(UIView *)aView {
        UIImage *viewImage;
    
        UIGraphicsBeginImageContextWithOptions(aView.bounds.size, aView.opaque, [[UIScreen mainScreen] 比例]);
        [aView.layer renderInContext:UIGraphicsGetCurrentContext()];
        viewImage = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        返回视图图像;
    }
    

The solution below works fine for me in exactly the same use case where I have to move to fullscreen mode with TabBar animation.

Basically, the idea is

  1. to make a snapshot of UITabBar;

  2. add the UIImage of the snapshot to UIImageView which has the same frame as UITabBar does;

  3. resize underlying view and place it on self.tabBarController.view;

  4. set UITabBar's alpha to be 0.0;

  5. place the UIImageView with UITabBar's snapshot on the self.tabBarController.view;

  6. 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;
    }
    
丿*梦醉红颜 2024-10-28 04:00:05

我几乎尝试了所有这些答案,但没有一个对我有用。我的应用程序有一个 UITabBarController 作为根视图,每个选项卡都有一个 UINavigationController。其中一个 UINavigationController 有一个 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];
        }
    }
}

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.

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:

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

- (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];
        }
    }
}
十级心震 2024-10-28 04:00:05

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

Swift and modified version of @Saurabh code

Method

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

To show

override func viewDidLoad() {
     setTabBarHidden(true)
}

To hide

override func viewWillDisappear(animated: Bool) {
    setTabBarHidden(false)
}
已下线请稍等 2024-10-28 04:00:05

带动画的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))!
 })

A swift version with animation, you need set a property isHideTabBar by yourself.

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))!
 })
够钟 2024-10-28 04:00:05

更新并适用于 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)
                        }
                    }
                })
            }
        })
    }
}

Updated and Working for swift 5 and 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)
                }
            }
        })
    }
}

This is a more direct port (not tested):

/*
    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)
                        }
                    }
                })
            }
        })
    }
}
毅然前行 2024-10-28 04:00:05

隐藏选项卡栏不是一个足够的解决方案,它不会调整当前视图控制器的视图高度。

相反,您可以简单地转换选项卡栏本身,无论是通过其高度(隐藏)还是身份转换以重置为可见。

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

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

Hiding the tab bar is not an adequate solution, it won't adjust the current view controllers view height.

Instead you may simply transform the tab bar itself, either by it's height (to hide) or an identity transform to reset to visible.

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

Note that you may need to set your view controller to 'extends below bottom bars' and 'extends under opaque bars' to remove the black background during animation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文