it-swarm.com.ru

Iphone: можно ли скрыть TabBar? (До iOS 8)

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

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

self.tabBarController.tabBar.hidden = YES

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

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

34
Steve

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

Это, конечно, смешно с goings on в иерархии представления контроллера. Это может измениться/сломаться. При этом используются определенные 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
}

Правка : Анонимный пользователь предложил следующее дополнение для 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 и, вероятно, отсутствует в некоторых макетах.

37
bshirley

Как и Стив, я не нашел чистого способа сделать это (хотя 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;
  }

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

9
Terence

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

    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. Не использовал его в действии кнопки, но если, как и я, вы не найдете ничего выше, теперь это работает, это может быть основой программируемого решения. 

8
GAllan

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

Как скрыть 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]; 
}
4
Ted

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

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

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

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

// In UITabBarController's 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: метод 

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

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

3
Abduliam Rehmanius

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

создать категорию #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 используется, когда hotspot или call включены, поэтому панель вкладок не будет сокращена.

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

[self.tabBarController hideTabBarAnimated:YES];

[self.tabBarController showTabBarAnimated:YES];

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

0
ChintaN -Maddy- Ramani

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

0
user2159978

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

 @ interface UITabBarController (Дополнения) 

- (void) setTabBarHidden: (BOOL) скрытый анимированный: (BOOL) анимированный; 

 @ end 

 @ реализация UITabBarController ( Дополнения) 

- (void) setTabBarHidden: (BOOL) скрытый анимированный: (BOOL) анимированный 
 {
 если (анимированный) 
 {
 [UIView beginAnimations: ноль контекст: ноль]; 
 } 
 если (скрыто) 
 {

 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) ; 
 } 
 еще 
 {
 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); 
 } 
 если (анимированный) 
 {
 [UIView commitAnimations]; 
 } 

} 

0
Amit Tandel

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

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

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

0
matt

Вот мое решение (мой контроллер представления вкладок находится внутри контроллера навигации для хорошей меры) ... Итак, я подкласс 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];
    }];
}
0
Cherpak Evgeny

поместите оператор в метод init UIViewController

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

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

view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

Нечто подобное должно сделать свое дело и позволить виду, находящемуся на вершине стека, изменить размер.

0
MystikSpiral