Iphone: Можно ли скрыть TabBar? (Pre-iOS 8)

У меня есть приложение, которое использует UITabBarController для переключения между режимами. Когда в определенном режиме я хотел бы скрыть панель вкладок до тех пор, пока шаги этого режима не будут завершены. Обратите внимание, что я не использую контроллер навигации, поэтому я не могу использовать метод setHidesBottomBarWhenPushed на контроллере навигации, чтобы скрыть панель вкладок.

До iOS 8, Когда я пытаюсь скрыть tarbar, используя:

self.tabBarController.tabBar.hidden = YES

панель вкладок уходит, но она оставляет пустую область размером 50 пикселей в нижней части экрана, где раньше была панель вкладок. Я не могу понять, как заполнить эту область. Все, что находится в пользовательском интерфейсе, который находится в этой области, обрезается и не отображается.

Любые идеи, если это возможно? Я действительно хотел бы держаться подальше от навигационного контроллера.

Ответ 1

Вот мой код для этого:

Это, конечно, ошибка, связанная с идеями в иерархии представления контроллера. Это может измениться/сломаться. Это использует определенные API-интерфейсы, поэтому Apple все равно, но они не заботятся о разрыве кода.

- (void)hideTabBar {
  UITabBar *tabBar = self.tabBarController.tabBar;
  UIView *parent = tabBar.superview; // UILayoutContainerView
  UIView *content = [parent.subviews objectAtIndex:0];  // UITransitionView
  UIView *window = parent.superview;

  [UIView animateWithDuration:0.5
                   animations:^{
                     CGRect tabFrame = tabBar.frame;
                     tabFrame.origin.y = CGRectGetMaxY(window.bounds);
                     tabBar.frame = tabFrame;
                     content.frame = window.bounds;
                   }];

  // 1
}

- (void)showTabBar {
  UITabBar *tabBar = self.tabBarController.tabBar;
  UIView *parent = tabBar.superview; // UILayoutContainerView
  UIView *content = [parent.subviews objectAtIndex:0];  // UITransitionView
  UIView *window = parent.superview;

  [UIView animateWithDuration:0.5
                   animations:^{
                     CGRect tabFrame = tabBar.frame;
                     tabFrame.origin.y = CGRectGetMaxY(window.bounds) - CGRectGetHeight(tabBar.frame);
                     tabBar.frame = tabFrame;

                     CGRect contentFrame = content.frame;
                     contentFrame.size.height -= tabFrame.size.height;
                   }];

  // 2
}

Edit: Анонимный пользователь предложил следующее дополнение для 7.0 (я не тестировал это и не мог сказать, является ли это обходным путем или идеальной реализацией):

// 1. To Hide the black line in IOS7 only, this extra bit is required
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
    [self.tabBarController.tabBar setTranslucent:YES];
}  

// 2. For IOS 7 only
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
    [self.tabBarController.tabBar setTranslucent:NO];
}

Изменить: полностью непроверено в 8.x и, вероятно, отсутствует в некоторых макетах.

Ответ 2

Как и Стив, я не нашел чистого способа сделать это (хотя Apple Photopicker делает что-то подобное). Вот что я сделал:

 if (systemAction)
  {
    // Reveal tab bar back
    CGRect bounds = [[UIScreen mainScreen] bounds];
    CGRect tabBarFrame = self.tabBarController.tabBar.frame;
    self.tabBarController.view.frame = CGRectMake(0,0,bounds.size.width,bounds.size.height);
    self.toolBar.hidden = YES;
    systemAction = NO;
  }
  else
  {
    //hide tab bar
    CGRect bounds = [[UIScreen mainScreen] bounds];
    CGRect tabBarFrame = self.tabBarController.tabBar.frame;
    CGRect navigationBarFrame = self.navigationController.navigationBar.frame;
    self.tabBarController.view.frame = CGRectMake(0,0,bounds.size.width,bounds.size.height+tabBarFrame.size.height);
    self.toolBar.hidden = NO;
    CGRect frame = self.toolBar.frame;
    frame.origin.y = bounds.size.height - frame.size.height - navigationBarFrame.size.height;
    self.toolBar.frame = frame;
    systemAction = YES;
  }

То, что он делает, - это нажать вниз, чтобы я мог отображать панель инструментов (а не скрывать ее). Очевидно, что это только для "корневого представления" на панели управления + навигационный контроллер. Для любых последующих представлений вы можете установить "hidesBottomBarWhenPushed" на вызываемый вами viewcontroller.

Ответ 3

Я попробовал несколько решений выше, но не радость в iOS 8. Я считаю, что настройка в viewWillAppear для меня работает. Должен работать в iOS 7, так как был расширен расширенныйLayoutIncludesOpaqueBars.

    self.extendedLayoutIncludesOpaqueBars = true
    self.tabBarController?.tabBar.isHidden = true
    self.tabBarController?.tabBar.isOpaque = true

и если вам нужно снова включить tabBars, когда вы уходите, чтобы использовать следующее в viewWillDisappear.

    self.tabBarController?.tabBar.isHidden = false
    self.tabBarController?.tabBar.isOpaque = false

Я использую это, чтобы вернуться от перехода, чтобы сохранить TabBar скрытым. Не использовать его в действии кнопки, но, если я, как и я, вы ничего не обнаружите выше, это может быть основой для программируемого решения.

Ответ 4

Это немного поздно в тот же день, но из всех ответов на вопрос, который я пролетел через этот день, это тот, который работал лучше всего для меня.

Как скрыть uitabbarcontroller

// Method call
[self hideTabBar:self.tabBarController];   

// Method implementations
- (void)hideTabBar:(UITabBarController *) tabbarcontroller
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.5];

    for(UIView *view in tabbarcontroller.view.subviews)
    {
        if([view isKindOfClass:[UITabBar class]])
        {
            [view setFrame:CGRectMake(view.frame.origin.x, 480, view.frame.size.width, view.frame.size.height)];
        } 
        else 
        {
            [view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 480)];
        }
    }

    [UIView commitAnimations];   
}

- (void)showTabBar:(UITabBarController *) tabbarcontroller
{       
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.5];
    for(UIView *view in tabbarcontroller.view.subviews)
    {
        NSLog(@"%@", view);

        if([view isKindOfClass:[UITabBar class]])
        {
            [view setFrame:CGRectMake(view.frame.origin.x, 431, view.frame.size.width, view.frame.size.height)];

        } 
        else 
        {
            [view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 431)];
        }
    }

    [UIView commitAnimations]; 
}

Ответ 5

Я использую только эту единственную линию для достижения этой цели. Я использую метод prepareForSegue перед отображением контроллера вида, имеющего панель вкладок.

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if([segue.identifier isEqualToString:@"showLogin"]){
        [segue.destinationViewController setHidesBottomBarWhenPushed:YES];
    }
}

Ответ 6

Я работал почти в одном и том же случае, фактически использовал код http://www.developers-life.com/hide-uitabbarcontrolleruitabbar-with-animation.html и сделал его лучше в соответствии с моими потребностями, это могло бы помогите другим тоже.

Я использую UISplitViewController в качестве контроллера корневого представления, а его детальная часть - UITabBarController, мне нужно было скрыть панель в портретном режиме:

// In UITabBarController custom implementation add following method, 
// this method is all that will do the trick, just call this method 
// whenever tabbar needs to be hidden/shown 
- (void) hidetabbar:(NSNumber*)isHidden {
    UITabBarController *tabBarController=self;

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.5];

    CGRect tabbarFrame=CGRectZero;
    for(UIView *theView in tabBarController.view.subviews) {
        //NSLog(@"%@", view);
        if([theView isKindOfClass:[UITabBar class]]) {
            tabbarFrame=theView.frame;
            if ([isHidden boolValue]) {
                tabbarFrame=CGRectMake(tabbarFrame.origin.x, 
                                       tabBarController.view.frame.size.height, 
                                       tabbarFrame.size.width, 
                                       tabbarFrame.size.height);
            } else {
                tabbarFrame=CGRectMake(tabbarFrame.origin.x, 
                                       tabBarController.view.frame.size.height - tabbarFrame.size.height, 
                                       tabbarFrame.size.width,
                                       tabbarFrame.size.height);
            }
            theView.frame=tabbarFrame;
            break;
        }
    }

    for(UIView *theView in tabBarController.view.subviews) {
        if(![theView isKindOfClass:[UITabBar class]]) {
            CGRect theViewFrame=theView.frame;
            if ([isHidden boolValue]) {
                theViewFrame=CGRectMake(theViewFrame.origin.x, 
                                        theViewFrame.origin.y, 
                                        theViewFrame.size.width, 
                                        theViewFrame.size.height + tabbarFrame.size.height);
            } else {
                theViewFrame=CGRectMake(theViewFrame.origin.x, 
                                        theViewFrame.origin.y, 
                                        theViewFrame.size.width, 
                                        theViewFrame.size.height - tabbarFrame.size.height);
            }
            theView.frame=theViewFrame;
        }
    }
    [UIView commitAnimations];
}

Я использовал следующий код для вызова hidetabbar: method

//In my UISplitViewController custom implementation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    @synchronized(self){
    //change the self.splitDetailController to your UITabBarController object
    [self.splitDetailController 
     performSelector:@selector(hidetabbar:) 
     withObject:[NSNumber numberWithBool:UIInterfaceOrientationIsLandscape(interfaceOrientation)]
     afterDelay:0.5];
    }
    return YES;
}

Я тестировал этот код для работы только в симуляторе, дайте мне знать, работает ли он на устройстве; -)

Ответ 7

У вас есть параметр autoResizingMask, установленный в подзаголовке?

view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

Что-то вроде этого должно сделать трюк и разрешить просмотр, сидящий поверх стека, для изменения размера.

Ответ 8

Очевидным решением, поддерживающим вашу оригинальную архитектуру, было бы представить это мнение по-разному:

- (void)tabBarController:(UITabBarController *)tb
 didSelectViewController:(UIViewController *)vc {
    if (tb.selectedIndex == MODALONE) {
        UIViewController* mod = 
            [[UIViewController alloc] initWithNibName: @"ModalView" 
                                               bundle: nil];
        [tb presentModalViewController:mod animated:NO];
        [mod release];
    }
}

Теперь представление охватывает весь экран (кроме строки состояния есть один), включая панель вкладок, поэтому выглядит так, как будто панель вкладок ушла в ответ на то, что пользователь нажимает этот элемент панели табуляции.

Ответ 9

авторезистирующая маска имеет нумерацию. Попробуйте установить все параметры и проверьте, включена ли опция autoresize subviews в родительском представлении

Ответ 10

Вы можете создать категорию табуляции и легко показать/скрыть. и вы можете получить доступ к полному просмотру.

создать категорию #import "UITabBarController+HideTabBar.h"

@implementation UITabBarController (HideTabBar)

- (void)hideTabBarAnimated:(BOOL)animated
{
    CGRect statusbarFrame = [UIApplication sharedApplication].statusBarFrame;
    CGRect tabBarControllerFrame = self.view.frame;
    if (statusbarFrame.size.height>20)
    {
        tabBarControllerFrame.size.height =  screenSize.size.height + self.tabBar.frame.size.height - 20.0;
    }
    else
    {
        tabBarControllerFrame.size.height = screenSize.size.height + self.tabBar.frame.size.height ;
    }

    if (animated) {
        [UIView animateWithDuration:0.2 animations:^{
            [self.view setFrame:tabBarControllerFrame];
        } completion:^(BOOL finished) {

        }];
    }
    else
        [self.view setFrame:tabBarControllerFrame];
}

- (void)showTabBarAnimated:(BOOL)animated {
    CGRect statusbarFrame = [UIApplication sharedApplication].statusBarFrame;
    CGRect tabBarControllerFrame = self.view.frame;
    if (statusbarFrame.size.height>20)
    {
        tabBarControllerFrame.size.height =  screenSize.size.height - 20.0;
    }
    else
    {
        tabBarControllerFrame.size.height = screenSize.size.height ;
    }

    if (animated) {
        [UIView animateWithDuration:0.2 animations:^{
            [self.view setFrame:tabBarControllerFrame];
        } completion:^(BOOL finished) {

        }];
    }
    else
        [self.view setFrame:tabBarControllerFrame];
}
@end

Примечание: использование statusbarFrame используется, когда горячая точка или вызов включены, поэтому таба не будет сокращаться.

Теперь импортируйте категорию, в которой вы хотите использовать методы, и просто вызовите методы ниже, чтобы скрыть или показать вкладку.

[self.tabBarController hideTabBarAnimated:YES];

[self.tabBarController showTabBarAnimated:YES];

Надеюсь, что это поможет.

Ответ 11

Надеюсь, что это сработает.

@interface UITabBarController (Additions)

-(void)setTabBarHidden:(BOOL)hidden animated:(BOOL)animated;

@end

@implementation UITabBarController (Additions)

-(void)setTabBarHidden:(BOOL)hidden animated:(BOOL)animated
{
    if (animated)
    {
        [UIView beginAnimations:nil context:nil];
    }
    if (hidden)
    {

        self.tabBar.frame = CGRectMake(self.tabBar.frame.origin.x, self.tabBar.superview.frame.size.height, self.tabBar.bounds.size.width, self.tabBar.bounds.size.height);
    }
    else
    {
        self.tabBar.frame = CGRectMake(self.tabBar.frame.origin.x, self.tabBar.superview.frame.size.height - self.tabBar.frame.size.height + 10, self.tabBar.bounds.size.width, self.tabBar.bounds.size.height);
    }
    if (animated)
    {
        [UIView commitAnimations];
    }

}

Ответ 12

Вот мое решение (мой контроллер представления таблиц находится внутри контроллера навигации для хорошей меры)... Итак, я подклассифицировал UITabBarController и сделал это... разоблачение метода -setTabBarHidden:

- (void)setTabBarHidden:(BOOL)hidden {
    _tabBarHidden = hidden;

    [UIView performWithoutAnimation:^{
        [self adjustViews];
    }];

}

- (void)adjustViews {
    if ( _tabBarHidden ) {
        CGRect f = self.tabBar.frame;

        // move tab bar offscreen
        f.origin.y = CGRectGetMaxY(self.view.frame);
        self.tabBar.frame = f;

        // adjust current view frame
        self.selectedViewController.view.frame = self.view.frame;
    } else {
        CGRect f = self.tabBar.frame;

        // move tab bar on screen
        f.origin.y = CGRectGetMaxY(self.view.frame) - (CGRectGetMaxY(self.tabBar.bounds) + CGRectGetMaxY(self.navigationController.navigationBar.frame));
        self.tabBar.frame = f;

        // adjust current view frame
        f = self.view.bounds;
        f.size.height -= CGRectGetMaxY(self.tabBar.bounds);
        self.selectedViewController.view.frame = f;
    }
}

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];

    [UIView performWithoutAnimation:^{
        [self adjustViews];
    }];
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    [UIView performWithoutAnimation:^{
        [self adjustViews];
    }];
}

Ответ 13

поместите инструкцию в метод init UIViewController

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        self.hidesBottomBarWhenPushed = true
        setupDependencyConfigurator()
    }

Ответ 15

Почему вы не используете навигационный контроллер. Гораздо проще скрыть навигационную панель, чем панель вкладок...

Ответ 16

Просто сделал следующий код в Monotouch внутри подкласса UITabBarController:

    public void ShowTabBar()
    {
        UIView.BeginAnimations("Anim");
        UIView.SetAnimationDuration(0.25f);
        this.View.Subviews[0].Frame = new RectangleF(0f, 0f, 320f, 431f);
        this.TabBar.Frame = new RectangleF(0f, 431f, 320f, 49f);
        this.TabBar.Hidden = false;
        UIView.CommitAnimations();
    }

    public void HideTabBar()
    {
        UIView.BeginAnimations("Anim");
        UIView.SetAnimationDuration(0.25f);
        this.View.Subviews[0].Frame = new RectangleF(0f, 0f, 320f, 480f);
        this.TabBar.Frame = new RectangleF(0f, 481f, 320f, 510f);
        this.TabBar.Hidden = true;
        UIView.CommitAnimations();          
    }