Як приховати uitabbarcontroller


75

У мене проблема з UITabBarController. У моїй програмі я хочу її приховати, але не використовуючи, hidesBottomBarWhenPushedтому що хочу приховати не тоді, коли я її натиснув. Наприклад, я хочу приховати це, коли натискаю кнопку "Сховати" у своєму додатку.

Я читав багато статей у google, але не можу дізнатись, як я можу це зробити.


Відповіді:


149

Я вставляю це зі свого робочого коду ... ви можете викликати ці методи, щоб приховати та показати 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]; 
}

яблуко дозволяє вам це робити? Я маю на увазі, що вкладку слід читати лише ... просто цікаво, чи не буде відхилено мою програму
mateusmaso

3
я намагаюся знайти це рішення. при виклику методу hideTabbar () моя панель вкладок - hide, але вона відображає пробіл внизу (розташуйте ту саму панель вкладок). як я можу це виправити?
Thunderbird

58

Модифікована відповідь 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, та переконався, що він працює належним чином, навіть коли пристрій лежить на спині.


10
Ви повинні замінити - 49.0з tabbarcontroller.tabBar.frame.size.heightбільш чистим кодом , який має менше шансів розриву в майбутніх версіях IOS.
Ітан Аллен,

34

У вашому методі дії для кнопки:

[self.tabBarController.tabBar setHidden:YES];

2
Цей метод працює в iOS 7, але в iOS 6 він залишить великий пробіл там, де була панель вкладок.
Даніал Айтекін

Для мене на iOS 13.3 це не спрацювало - зникає, але залишає порожній простір.
Микола Суванджієв

ви пробували "underOpaqueBars" та інше в розділі "Інформація про контролер перегляду"
Moose

12

Рішення Saurahb та karlbecker_com є чудовими, хоча вони можуть спричинити очевидний спливаючий ефект, коли подання містить табличний перегляд, а панель вкладок анімує резервне копіювання. Я вніс деякі модифікації та об’єднав їх в єдину функцію (як категорію на 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];

9

Відповідь Саураба вище можна поширити і на роботу в альбомній орієнтації:

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

`

Відповідними номерами x_pos для showTabBar () є 431та 271.


4

Відповідь @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];
}  

4

Це відповідь 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

Починаючи з IOS 7.1, "швидкі" рішення:

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

Сподіваюся, це може допомогти!


1
Однак це не коригує простір вмісту контролерів перегляду. Залишає вільну ділянку.
tcurdt

3

Ви можете натиснути на модальний контролер перегляду

[self presentModalViewController:myFullscreenViewController animated:YES];

це створить абсолютно новий повноекранний вигляд над вашим поточним.

звільнити іст с dismissModalViewController:animated:


3

Рішення, наведене нижче, чудово працює для мене саме в тому самому випадку використання, коли мені доводиться переходити в повноекранний режим з анімацією TabBar.

В основному, ідея така

  1. зробити знімок UITabBar ;

  2. додати UIImage знімка до UIImageView, який має той самий кадр, що і UITabBar ;

  3. змінити розмір основного подання та розмістити його на self.tabBarController.view ;

  4. встановити альфа- значення UITabBar рівним 0,0;

  5. розмістіть UIImageView зі знімком UITabBar на 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

Я спробував майже всі ці відповіді, але жодна з них не спрацювала для мене. У моєму додатку в якості кореневого подання є UITabBarController, а кожна вкладка має UINavigationController. Один з контролерів UINavigationControllers має 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

в iOS8 досить просто встановити hiddenвластивість tabBar
Like у Swift, яку ви можете

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

Я роблю це в моєму didFinishLaunchingWithOptionsв appdelegateі вона відмінно працює, я думаю , якщо я правильно пам'ятаю , в старих версіях IOS ви також необхідні для установки frameз tabBarдо чого - то за межами екрану, в іншому випадку tabbarне було б показати , але вона по- , як і раніше буде займати простір.


Хіба це просто не робить його невидимим? Він все ще там і буде перешкоджати клацанню речей під ним.
h3dkandi

2

Швидка та модифікована версія коду @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)
}

1

Ось швидкий порт швидкої версії @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

Швидка версія з анімацією, вам потрібно встановити властивість 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

Приховування панелі вкладок не є адекватним рішенням, це не призведе до регулювання поточної висоти подання контролерів перегляду.

Натомість ви можете просто перетворити саму панель вкладок, або за її висотою (щоб приховати), або перетворення ідентифікатора, щоб скинути її до видимої.

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

Зверніть увагу, що вам може знадобитися встановити для вашого контролера перегляду значення "розширюється нижче нижньої смуги" та "поширюється під непрозорими смугами", щоб видалити чорний фон під час анімації.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.