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()
}
Ответ 14
Смотрите эту тему:
Показать/скрыть TabBarController в iphone
Вкратце, вы можете увидеть пример этого поведения в этом примере кода:
http://developer.apple.com/iphone/library/samplecode/TheElements/index.html
Ответ 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();
}