隐藏 UIStatusBar / 移动 UINavigationBar

Posted

技术标签:

【中文标题】隐藏 UIStatusBar / 移动 UINavigationBar【英文标题】:Hiding UIStatusBar / Moving UINavigationBar 【发布时间】:2011-07-29 08:25:56 【问题描述】:

我有一个基于导航的应用程序,用户可以在其中隐藏状态栏。这在默认设置中被记住。

它大部分都在工作,除了一个例外,如果应用程序被加载(从头开始,返回主屏幕后没有返回),当状态栏应该可见时,当它切换到不可见时,导航条不向上移动以填满屏幕。之后切换设置可以正确地上下移动导航栏,但导航栏和屏幕顶部或状态栏之间仍然存在额外的状态栏大小的间隙。如果我返回主屏幕并重新进入应用程序,这会自行纠正。因此,我假设在切换状态栏后返回到我需要调用的应用程序时,在 uinavigationcontroller 上调用了一些方法?

我已经尝试过(我认为)wantsfullscreenlayout 属性的所有组合,我在下面的方法中设置它但没有任何区别,所以我最终在笔尖中将它(在导航控制器上)设置为 NO。

这是切换状态栏的代码。这是在我的应用程序委托中,它根据模板应用程序将导航控制器和窗口设置为出口。

if ([UIApplication sharedApplication].statusBarHidden != hideStatusBar)

    [[UIApplication sharedApplication] setStatusBarHidden:hideStatusBar withAnimation:UIStatusBarAnimationSlide];
    [UIView animateWithDuration:0.25 animations:^
        window.frame = [[UIScreen mainScreen] applicationFrame];
    ];

else

    window.frame = [[UIScreen mainScreen] applicationFrame];

感谢您的帮助。

更新

通过 NSLogging,问题似乎在于 UINavigationBar 的框架。所以我添加了以下代码,它可以工作和动画,但我不满意!我不觉得这可能是做到这一点的“正确”方式。在大多数情况下,额外的代码什么都不做,因为帧已经在 (0,0),但是在它不正确的一种情况下,这会给出正确的结果。

[navigationController.view setNeedsLayout];
CGRect navBarFrame;
UINavigationBar *navBar = nil;
for (UIView *subView in navigationController.view.subviews)

    if ([subView isMemberOfClass:[UINavigationBar class]])
    
        navBar = (UINavigationBar *)subView;
        navBarFrame = navBar.frame;
        navBarFrame.origin = CGPointMake(0,0);
        break;
    


if ([UIApplication sharedApplication].statusBarHidden != hideStatusBar)

    [[UIApplication sharedApplication] setStatusBarHidden:hideStatusBar withAnimation:UIStatusBarAnimationSlide];
    [UIView animateWithDuration:0.25 animations:^
        window.frame = [[UIScreen mainScreen] applicationFrame];
        navBar.frame = navBarFrame;
    ];

else

    window.frame = [[UIScreen mainScreen] applicationFrame];

【问题讨论】:

尝试调用 [self.view setNeedsDisplay] 没有self.view,这是在应用程序委托中。你是说navigationController.view吗? 是的,不管当前视图是什么 如果您使用 IB 添加导航栏,您可以尝试使用显示的箭头将其附加到窗口顶部。只是一个随机的建议 【参考方案1】:

窗口始终位于状态栏下方,因此您不应尝试调整它的大小。

改为将窗口的根视图控制器的视图大小调整为[[UIScreen mainScreen] applicationFrame]

【讨论】:

窗口没有设置rootviewcontroller outlet,这应该是导航控制器吗? 是的。对不起,我应该更清楚。调整您在applicationDidFinishLaunching:withOptions: 中添加为窗口子视图的任何视图的大小(几乎可以肯定是您的导航控制器的视图)。 rootViewController 属性是您可以设置它的新方法,但大多数应用程序仍然只是将视图控制器的视图添加为窗口的子视图。 结果和以前一样。 哦,对了。我忘记了隐藏状态栏时 UINavigationController 不会自动响应。一种可行的方法是从 winodw 中删除导航控制器的视图并立即重新添加它。我会到处玩,看看能不能找到更优雅的东西。 好吧,我发现你不需要删除并重新添加导航控制器。您可以使用[self.navigationController setNavigationBarHidden:YES animated:NO]; [self.navigationController setNavigationBarHidden:NO animated:NO]; 切换导航栏的可见性。这会强制导航控制器调整导航栏布局,但动画效果不佳。所以你的 hack 可能会更好。【参考方案2】:

问题在于 UINavigationBar 的框架。所以我添加了以下代码,它可以工作和动画,但我不满意!我不觉得这可能是做到这一点的“正确”方式。在大多数情况下,额外的代码什么都不做,因为帧已经在 (0,0),但在它不正确的一种情况下,这会给出正确的结果。

[navigationController.view setNeedsLayout];
CGRect navBarFrame;
UINavigationBar *navBar = nil;
for (UIView *subView in navigationController.view.subviews)

    if ([subView isMemberOfClass:[UINavigationBar class]])
    
    navBar = (UINavigationBar *)subView;
    navBarFrame = navBar.frame;
    navBarFrame.origin = CGPointMake(0,0);
    break;
    


if ([UIApplication sharedApplication].statusBarHidden != hideStatusBar)

    [[UIApplication sharedApplication] setStatusBarHidden:hideStatusBar withAnimation:UIStatusBarAnimationSlide];
    [UIView animateWithDuration:0.25 animations:^
    window.frame = [[UIScreen mainScreen] applicationFrame];
    navBar.frame = navBarFrame;
    ];

else

    window.frame = [[UIScreen mainScreen] applicationFrame];

【讨论】:

【参考方案3】:

据我所知,如果您隐藏状态栏,您的视图会自动占据新空间,而您不必手动更改窗口框架。如果你只尝试这个会发生什么

if ([UIApplication sharedApplication].statusBarHidden != hideStatusBar)

    [[UIApplication sharedApplication] setStatusBarHidden:hideStatusBar withAnimation:UIStatusBarAnimationSlide];

【讨论】:

导航栏留在原处 - 这是我最初开始的地方,试图隐藏状态栏并在导航控制器上设置 Wantsfullscreenlayout 属性。【参考方案4】:

这就是为我解决的问题

只是一个视图:

[self.view setFrame: [self.view bounds]];

内部带有滚动视图的视图

[self.view setFrame: [self.view bounds]];
[self.theScroller setFrame: [self.view bounds]];

"theScroller 是我的滚动视图的名称

【讨论】:

以上是关于隐藏 UIStatusBar / 移动 UINavigationBar的主要内容,如果未能解决你的问题,请参考以下文章

如何检测 UIStatusBar 隐藏和显示?

UIStatusBar样式与UINavigationBar一致

如何在 iOS 应用程序中完全删除 UIStatusBar?

UIStatusBar iOS上状态栏的自定义颜色

在 iOS 中导航期间更改 UITabBar

UIStatusBar setTranslucent:NO 避免下移内容