iOS隐藏和取消隐藏状态栏未正确移动子视图
我有一个自定义视图控制器,可以包含两个子视图控制器。当设备处于纵向时,其中一个控制器的视图可见。当设备处于横向时,另一个控制器的视图可见。但是,当横向视图可见时,状态栏会缩回,以便为特定视图留出更多空间。设备返回纵向模式后,状态栏将取消隐藏。这是自定义视图控制器,显示在iOS隐藏和取消隐藏状态栏未正确移动子视图,ios,user-interface,statusbar,uiinterfaceorientation,Ios,User Interface,Statusbar,Uiinterfaceorientation,我有一个自定义视图控制器,可以包含两个子视图控制器。当设备处于纵向时,其中一个控制器的视图可见。当设备处于横向时,另一个控制器的视图可见。但是,当横向视图可见时,状态栏会缩回,以便为特定视图留出更多空间。设备返回纵向模式后,状态栏将取消隐藏。这是自定义视图控制器,显示在UINavigationController中 我的问题是,当状态栏的可见性更改时,我的子视图没有正确调整。当您以下图所示的不同方向转动设备时,会出现较大的间隙和/或重叠: 正如您所看到的,它最初很好(在纵向),但当设备转动时,
UINavigationController
中
我的问题是,当状态栏的可见性更改时,我的子视图没有正确调整。当您以下图所示的不同方向转动设备时,会出现较大的间隙和/或重叠:
正如您所看到的,它最初很好(在纵向),但当设备转动时,状态栏所在的位置有一个白色的间隙。当设备返回到纵向时,UINavigationController
的导航栏将被状态栏打开并重叠,导航栏与下方视图之间出现间隙。如果您很快地从一个横向方向旋转180度到另一个横向方向,则间隙会消失,看起来很好
下面的方法属于自定义视图控制器,在WillAnimateRotationInterfaceOrientation:duration:
(显然是为了处理旋转事件)和视图显示:
(为了处理从导航堆栈中的上一个视图控制器中推入的视图)
非常感谢所有能抽出时间来研究这个问题的人。很多人似乎都有这个问题,就像我一样,还有其他的问答线索,你应该去寻找——我可能永远也找不到神奇的答案。在某些情况下,您可能会尝试一个看似“修复”问题的难题,即当您将状态栏的可见性更改为(重新)显示状态栏时:
- 隐藏导航栏李>
- 取消隐藏状态栏李>
- 取消隐藏导航栏
dispatch_async(dispatch_get_main_queue(), ^{
[self.navigationController setNavigationBarHidden:NO animated:NO];
});
在反复摆弄之后,我似乎想出了某种解决办法。它似乎没有失败 这是我的密码:
- (void)cueAnimationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation fromViewDidAppear:(BOOL) fromViewDidAppear
{
// Fading animation during orientation flip.
// Make sure its not already animating before trying.
BOOL barHidden = [UIApplication sharedApplication].statusBarHidden;
if (!isAnimating) {
BOOL alreadyGoodGrid = (UIInterfaceOrientationIsLandscape(interfaceOrientation) && curView == self.gridViewController.view);
BOOL alreadyGoodTable = (UIInterfaceOrientationIsPortrait(interfaceOrientation) && curView == self.tableViewController.view);
if ((alreadyGoodGrid && barHidden) ||
(alreadyGoodTable && !barHidden)) {
// If views are the way they should be for this orientation. Don't do
// anything.
return;
}
isAnimating = YES;
UIView *nextView;
// Get starting orientation. This will determine what view goes on top
if (UIInterfaceOrientationIsLandscape(interfaceOrientation))
nextView = self.gridViewController.view;
else
nextView = self.tableViewController.view;
if (nextView == self.tableViewController.view)
{
if (!alreadyGoodTable)
{
self.tableViewController.view.alpha = 0.0;
[self.view bringSubviewToFront:self.tableViewController.view];
}
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
}
else
{
if (!alreadyGoodGrid)
{
self.gridViewController.view.alpha = 0.0;
[self.view bringSubviewToFront:self.gridViewController.view];
}
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
}
[UIView animateWithDuration:0.4
delay: 0.0
options: UIViewAnimationOptionAllowUserInteraction
animations:^{
CGRect r = self.navigationController.navigationBar.frame;
if (nextView == self.tableViewController.view) {
self.tableViewController.view.alpha = 1.0;
self.navigationController.navigationBar.frame = CGRectMake(0.0, 20.0, r.size.width, r.size.height);
self.view.frame = CGRectMake(0.0, 20.0, self.view.frame.size.width, self.view.frame.size.height - 20.0);
}
else {
self.gridViewController.view.alpha = 1.0;
self.navigationController.navigationBar.frame = CGRectMake(0.0, 0.0, r.size.width, r.size.height);
double y = 0.0, h = 0.0;
if (fromViewDidAppear)
{
y = -20.0;
h = 20.0;
}
self.view.frame = CGRectMake(0.0, y, self.view.frame.size.width, self.view.frame.size.height + h);
}
}
completion:^(BOOL finished) {
if (nextView == self.tableViewController.view) {
curView = self.tableViewController.view;
}
else {
curView = self.gridViewController.view;
}
isAnimating = NO;
}];
}
}
我要做的是检查该方法是从
viewdide:
还是从其他地方调用的(在本例中,仅willanimaterotationInterfaceOrientation:duration:
)。根据调用方法的人的不同,情况会有所不同。在这两种情况下,我都会调整self.view.frame
和self.navigationController.navigationBar.frame
,以说明状态栏位置的差异。当我们从视图查看时,显示:
我需要输入状态栏高度的负y值,以使子视图正确向上移动。这一切似乎都运行得相当好。在状态栏和导航栏被隐藏后,我遇到了同样的问题,然后再次显示。我在github上找到了一个解决方案(请参见showUI
method),并对其进行了修改以满足我的需要
- (void)toggleNavBar:(BOOL)hide
{
navBarHidden = hide;
//Fade status bar
[[UIApplication sharedApplication] setStatusBarHidden:hide
withAnimation:UIStatusBarAnimationFade];
//Fade navigation bar
[UINavigationBar beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.3]; // Approximately the same time the status bar takes to fade.
self.navigationController.navigationBar.alpha = hide ? 0 : 1;
[UINavigationBar commitAnimations];
// Being invisible messes with the position of the navigation bar, every time it gets
// visible we need to set it to the correct y-offset (just below the status bar)
[self adjustNavBarOrigin];
}
-(void)adjustNavBarOrigin
{
CGRect r = self.navigationController.navigationBar.frame;
r.origin.y = 20; //Height of the statusbar, can't find a reliable method in the SDK to get this value
self.navigationController.navigationBar.frame = r;
}
对于ios7,重写prefersStatusBarHidden
- (BOOL)prefersStatusBarHidden {
return NO if landscape and NO if landscape;
}
更改方向时,调用下面的函数以触发prefersStatusBarHidden函数
[self setNeedsStatusBarAppearanceUpdate];
请参阅中的详细答案,这解决了我的问题:
self.automaticallyAdjustsScrollViewInsets = false
谢谢你的帮助。投你一票。我最终找到了另一个似乎很有效的解决方案,我只是将其作为一个答案发布。很高兴你找到了一些东西——也许它会帮助我!你能在回答中解释一下为什么它解决了你的问题吗?我的问题是,当我试图在包含子视图的视图中隐藏导航/状态栏时,子视图会随着顶部栏移动。最近我发现问题在于插入设置。
self.automaticallyAdjustsScrollViewInsets = false