web-dev-qa-db-ja.com

uitabbarcontrollerを非表示にする方法

UITabBarControllerに問題があります。アプリケーションでは、hidesBottomBarWhenPushedを使用せずに非表示にします。プッシュしたときではなく非表示にするためです。たとえば、アプリケーションで非表示ボタンを押したときに非表示にします。

私はグーグルで多くの記事を読みましたが、どうすればこれができるかわかりません。

75
Viktor Apoyan

私は作業コードからこれを貼り付けています...これらのメソッドを呼び出して、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]; 
}
149
Saurabh

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

また、UIDeviceの向きの変更によりiOS 6で導入された変更を処理し、デバイスが仰向けになっている場合でも適切に動作するようにコードを変更しました。

58
karlbecker_com

ボタンのアクションメソッドで:

[self.tabBarController.tabBar setHidden:YES];
34
Sailesh

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];
12
Thomas Verbeek

上記の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番号は431および271

9
Setomidor

これは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();
}
4
Diego

@karlbecker_com Answerは、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];
}  
4
mikemike396

IOS 7.1、"Swift"ソリューション:

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

これが役立つことを願っています!

4
Sifeng

私はこれらすべての答えをほとんど試しましたが、どれも私のために働きませんでした。私のアプリにはルートビューとしてUITabBarControllerがあり、各タブにはUINavigationControllerがあります。 UINavigationControllersの1つには、トップビューコントローラーとして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];
        }
    }
}
3
SeanR

以下のソリューションは、TabBarアニメーションでフルスクリーンモードに移行する必要があるまったく同じユースケースでうまく機能します。

基本的に、アイデアは

  1. ITabBar;のスナップショットを作成します。

  2. スナップショットのIImageIImageViewに追加します。これはITabBarと同じフレームを持ちます。

  3. 基礎となるビューのサイズを変更し、それをself.tabBarController.viewに配置します。

  4. ITabBarのアルファを0.0に設定します。

  5. IImageViewITabBarのスナップショットをself.tabBarController.view;に配置します

  6. 上記が達成されたら、あらゆる種類のアニメーションを実行します

    #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;
    }
    
3
Yevhen Dubinin

モーダルビューコントローラをプッシュできます

[self presentModalViewController:myFullscreenViewController animated:YES];

これにより、現在のビューの上に完全に新しいビューのフルスクリーンが作成されます。

dismissModalViewController:animated:でistを却下します

3
user207616

iOS8では、hiddentabBarプロパティを設定するだけで十分です。
Like in Swift you can can

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

didFinishLaunchingWithOptionsappdelegateでこれを行い、正常に動作します。古いiOSバージョンで正しく覚えていれば、frametabBarも設定する必要があります。 _画面外の何かに、そうでなければtabbarは表示されませんが、それでもスペースを占有します。

3
Ali

@Saurabhコードの迅速な修正バージョン

メソッド

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

以下は、スリム化されたSwiftテーブルなしのVCの@Thomas Verbeekのバージョンの移植版です(iOS 8.4でテスト済み):

extension UITabBarController {

    /**
    Shows or hides the tabbar

    :param: hidden            whether to show or hide the tabbar
    :param: animationDuration the animation's duration
    */
    func setHidden(hidden:Bool, animationDuration:NSTimeInterval = 0.25) {

        let screenRect = UIScreen.mainScreen().bounds
        var fHeight = screenRect.size.height

        if !hidden {
            fHeight -= self.tabBar.frame.size.height
        }

        UIView.animateWithDuration(animationDuration, animations: {
                for view in self.view.subviews as! [UIView] {
                    if view is UITabBar {
                        view.frame = CGRectMake(
                            view.frame.Origin.x,
                            fHeight,
                            view.frame.size.width,
                            view.frame.size.height)
                    }
                }
            })
    }
}

そして、ここでより直接的なポート(テストされていません):

extension UITabBarController {

    /**
    Shows or hides the tabbar

    :param: hidden            whether to show or hide the tabbar
    :param: animationDuration the animation's duration
    */
    func setHidden(hidden:Bool, animationDuration:NSTimeInterval = 0.25) {

        let screenRect = UIScreen.mainScreen().bounds
        var fHeight = screenRect.size.height

        if UIInterfaceOrientationIsLandscape(UIApplication.sharedApplication().statusBarOrientation) {
            fHeight = screenRect.size.width
        }

        if !hidden {
            fHeight -= self.tabBar.frame.size.height
        }

        UIView.animateWithDuration(animationDuration, animations: {
                for view in self.view.subviews as! [UIView] {
                    if view is UITabBar {
                        view.frame = CGRectMake(
                            view.frame.Origin.x,
                            fHeight,
                            view.frame.size.width,
                            view.frame.size.height)
                    }
                    else if hidden {
                        view.frame = CGRectMake(
                            view.frame.Origin.x,
                            view.frame.Origin.y,
                            view.frame.size.width,
                            fHeight)
                    }
                }
            }, completion: { finished in
                if !hidden {
                    UIView.animateWithDuration(animationDuration, animations: {
                        for view in self.view.subviews as! [UIView] {
                            if !(view is UITabBar) {
                                view.frame = CGRectMake(
                                    view.frame.Origin.x,
                                    view.frame.Origin.y,
                                    view.frame.size.width,
                                    fHeight)
                            }
                        }
                    })
                }
        })
    }
}
1
svrs

A 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))!
 })
0
William Hu

タブバーを非表示にすることは適切な解決策ではなく、現在のView Controllerのビューの高さを調整しません。

代わりに、タブバー自体の高さ(非表示にする)またはID変換を表示するようにリセットするだけで、タブバー自体を単純に変換できます。

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

アニメーション中に黒の背景を削除するには、View Controllerを「下のバーの下に延長」および「不透明なバーの下に延長」に設定する必要がある場合があることに注意してください。

0
cdstamper