隐藏导航栏和标签栏时,UIView不会调整为全屏
我有一个应用程序,有一个标签栏和导航栏进行正常的交互。 我的一个屏幕是文本的一大部分,所以我允许用户点击去全屏(有点像Photos.app)。
导航栏和标签栏是隐藏的,我把文本视图的框架设置为全屏。 问题是,标签栏曾经是空白的大约50px。 你可以看到,如果从这个屏幕截图:
删除了死的ImageShack链接
我不确定是什么原因造成的。 空格绝对不是文本视图背后的视图,因为我把它的背景颜色设置为红色只是为了确保。 什么可能导致这个?
**更新**
我在UIWindow子类中做了一些命中testing,发现这个空白实际上是未公开/未发布的UILayoutContainerView。 这是tabBar的父视图。 我不认为这是build议直接操纵这个视图,所以我怎么能隐藏标签栏?
**更新#2 **
我在animation之前和之后检查了self.view的框架,看起来像父视图没有足够的大小。
进入全屏后,视图的帧只有411像素高。 我试图手动搞乱框架,也没有运气设置autoResizeMask。
****更新:这是最终结果****
- (void)toggleFullscreen { isFullScreen = !isFullScreen; //ivar //hide status bar & navigation bar [[UIApplication sharedApplication] setStatusBarHidden:isFullScreen animated:YES]; [self.navigationController setNavigationBarHidden:isFullScreen animated:YES]; [UIView beginAnimations:@"fullscreen" context:nil]; [UIView setAnimationBeginsFromCurrentState:YES]; [UIView setAnimationDuration:.3]; //move tab bar up/down CGRect tabBarFrame = self.tabBarController.tabBar.frame; int tabBarHeight = tabBarFrame.size.height; int offset = isFullScreen ? tabBarHeight : -1 * tabBarHeight; int tabBarY = tabBarFrame.origin.y + offset; tabBarFrame.origin.y = tabBarY; self.tabBarController.tabBar.frame = tabBarFrame; //fade it in/out self.tabBarController.tabBar.alpha = isFullScreen ? 0 : 1; //resize webview to be full screen / normal [webView removeFromSuperview]; if(isFullScreen) { //previousTabBarView is an ivar to hang on to the original view... previousTabBarView = self.tabBarController.view; [self.tabBarController.view addSubview:webView]; webView.frame = [self getOrientationRect]; //checks orientation to provide the correct rect } else { [self.view addSubview:webView]; self.tabBarController.view = previousTabBarView; } [UIView commitAnimations]; }
(请注意,我将textview切换到webview,但原始文本视图的作品相同)
我有这个确切的问题,我在屏幕的底部和顶部的标签栏和导航栏分别animation,留下一个49px高的白色空间的标签栏。
事实certificate,我新的“全屏”视图实际上并没有填充空间的原因是因为我将全屏视图添加为导航控制器视图的子视图,该视图本身是标签栏控制器的子视图。
为了解决这个问题,我简单地把新的全屏视图(在你的情况下是所有文本视图)添加为UITabBarController视图的子视图。
[[[self tabBarController] view] addSubview:yourTextView];
然后你需要做的就是确保你的子视图的框架是480×320像素,它应该填满屏幕(包括以前是神秘的空白区域)
你可以通过改变视图的框架,使标签栏离开屏幕,来确定显示正确的东西。 我知道其他人提到了这个问题,而且你说这是行不通的,但是我怀疑问题在于你没有正确的设置textviewsresize掩码。 以下是应该工作的代码:
- (void)viewDidLoad { [super viewDidLoad]; currentlyHidden = NO; } - (void) hideStuff { SO2AppDelegate *appDelegate = (id)[[UIApplication sharedApplication] delegate]; self.navigationController.navigationBarHidden = YES; CGRect newFrame = appDelegate.tabBarController.view.frame; newFrame.size.height += appDelegate.tabBarController.tabBar.frame.size.height; appDelegate.tabBarController.view.frame = newFrame; } - (void) showStuff { SO2AppDelegate *appDelegate = (id)[[UIApplication sharedApplication] delegate]; CGRect newFrame = appDelegate.tabBarController.view.frame; newFrame.size.height -= appDelegate.tabBarController.tabBar.frame.size.height; appDelegate.tabBarController.view.frame = newFrame; self.navigationController.navigationBarHidden = NO; } - (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { if (currentlyHidden) { [self showStuff]; currentlyHidden = NO; } else { [self hideStuff]; currentlyHidden = YES; } }
另外,由于这对你的笔尖等设置是非常敏感的,所以我在网上发布了一个项目,所以你可以下载它并看看它。 这是一个非常简单的演示,只是一个基于导航的项目,其中委托设置一个选项卡控制器,并从主要的笔尖embedded视图控制器。 剩下的就在RootViewController的nib和class中。 只要触摸开始,酒吧是切换,所以只需点击屏幕。 显然,在一个真正的应用程序中,您可能需要调整滚动视图,以便内容不会跳转。
你有没有把你的视图控制器的hidesBottomBarWhenPushed
属性设置为YES
? 你需要在initWithNibName:bundle:
或initWithCoder:
方法中设置它。 当它被推送到导航控制器,这应该隐藏标签栏,并使内容视图向下延伸到底部。
也许还有另一个视图是标签栏区域的内置部分? 也就是说,还有一些可以隐藏的东西。 这将帮助你看到什么意见。
for (UIView *viewy in [self.navigationController.view subviews]) { NSLog([viewy description]); }
我发现,如果你标记新的视图,你将会推入导航堆栈,下面的行隐藏标签栏,只要它在堆栈上。
scrollViewController.hidesBottomBarWhenPushed = YES;
我相信问题是你仍然在标签栏控制器,我也碰到了一些问题,最后创build了两个视图,我的应用程序委托来控制,标签栏控制器和一个单独的uiview它包含标签栏控制器试图执行的任何操作。 您可以将您的视图传递给应用程序委托并在那里使用它?
尝试使TabBarControllers视图大于屏幕,以便标签栏隐藏在屏幕外,只要您在设置新的ViewController 之前执行此操作,那么其视图将resize以填充新框架!
在我的testing中,我使用了tabBarController:shouldSelectViewController:delegate方法来检查哪个视图控制器即将成为当前并相应地设置TabBarController.view.frame。 例如:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController { if( viewController == second) tabBarController.view.frame = CGRectMake( 0, 20, 320, 500); else tabBarController.view.frame = CGRectMake( 0, 20, 320, 460); }
如果这仍然不是您所需要的,请尝试查看UIViewController的HidesBottomBarWhenPushed属性。 当设置为yes时,如果控制器被压入导航堆栈,这将使底部栏隐藏。
当您select全屏时,我会将视图移动到窗口。 例如
myView = [self.view retain]; self.view = nil; [window addSubview:myView];
并回去:
[myView removeFromSuperView]; self.view = myView; [myView release]; myView = nil;
通过添加视图作为窗口的子窗口,它可以完全全屏,并将在标签栏顶部。
你可以结合这一点
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRotate:) name:@"UIDeviceOrientationDidChangeNotification" object:nil];
检测旋转。 (我认为你结合这个view.transform = CGAffineTransformMakeRotation使其旋转…?)
我有类似的问题。 正如Harry所说,这是导航控制器是Tab Bar Controller内部控制器的一个原因。 find另一种方法如何重绘您的视图,并有正确的框架。,在你的控制器添加以下内容:
- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; // Here you can make your tabBarControlelr.view.hidde = true or use any animation that hides UITabBar. I made [TabBarController setTabBarHidden:YES]; self.navigationController.view.frame = CGRectMake(self.navigationController.view.frame.origin.x, self.navigationController.view.frame.origin.y, self.navigationController.view.frame.size.width, self.navigationController.view.frame.size.height + 50); [self.navigationController.view setNeedsLayout]; }
这是我如何隐藏它。 我可以直接调用TabBarControlelr或类方法包装器的方法:
+ (void)setTabBarHidden:(BOOL)hidden { AppDelegate *delegate = [UIApplication sharedApplication].delegate; TabBarController *tabBarController = (TabBarController *) delegate.window.rootViewController; if ([tabBarController isKindOfClass:[TabBarController class]]) { [tabBarController setTabBarHidden:hidden]; } } - (void)setTabBarHidden:(BOOL)hidden { if (self.tabBar.hidden == hidden) { return; } if (hidden == NO) { self.tabBar.hidden = hidden; } [UIView animateWithDuration:0.15 animations:^{ self.tabBar.frame = CGRectOffset(self.tabBar.frame, 0, ( hidden ? 50 : -50 )); } completion:^(BOOL finished) { self.tabBar.hidden = hidden; }]; }
如果您正在使用Interface Builder,请确保在“大小”检查器中正确设置自动resize。 如果您在代码中创buildUITextView,请确保将帧设置得足够大,并且视图的父级(以及它的父级)也足够大。 为了简单起见,直接将视图添加到窗口,然后从那里向内移动。
将视图移至其超级视图:
- (void)moveViewToSuperview:(UIView *)view { UIView *newSuperview = [[view superview] superview]; [view removeFromSuperview]; [newSuperview addSubview:view]; [newSuperview bringSubviewToFront:view]; }
你是否试图强制文本“重写”本身(重置所使用的任何对象的.text属性)? 我有很多实例,其中的观点根本不重新检查或重新绘制数据,强制似乎是唯一的解决办法。 如果从用户体验的angular度来看这是不好的,你可以尝试在用户触摸之后,在他们消失之前使导航/标签栏变为透明。 这通常将视图扩展到屏幕的整个大小。
如果UITabBarController被一个rootViewController(navigationController)推送。 您可以尝试以下方法:
首先隐藏状态栏/标签栏;
[self.navigationController pushViewController:aBlankViewController animated:NO]; [self.navigationController popViewControllerAnimated:NO];
你应该能够回收白色空间,虽然在调整过程中屏幕会震动…
我遇到了类似的问题,这个讨论是有帮助的: UIWebView在iPad的大小
Tony的回答帮助我发现,当你创build一个子视图时,设置与此相似的代码是很有帮助的:
self.tabBarController.tabBar.frame = self.view.bounds;
把代码放在这样的准备阶段,对我来说是完美的:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([[segue identifier] isEqualToString:@"ViewPhoto"]) { ImageView *vc = [segue destinationViewController]; NSInteger selectedIndex = [[self.tableView indexPathForSelectedRow] row]; NSString *Title = [photoNames objectAtIndex:selectedIndex]; [vc setSelectedTitle:[NSString stringWithFormat:@"%@", Title]]; vc.hidesBottomBarWhenPushed = YES; } }
将额外的空间添加到视图的维度,所以如果它是矩形CGRectMake(0,0,320,460)使它CGRectMake(0,0,320,480)…这发生在我身上,我不完全确定为什么,它可能你要把你的文本视图置于底层视图的基础视图,但只是添加维度应该这样做