当隐藏状态栏时,如何让UINavigationController中的导航栏更新其位置?

时间:2010-03-06 19:45:30

标签: iphone

我有一个带有可见导航栏的UINavigationController。 我有一个特殊的UIViewController,我想在推入导航堆栈时隐藏状态栏。弹出这个viewController后,我想再次显示状态栏。

我正在隐藏我viewWillAppear UIViewController方法中的栏,如下所示:

- (void) viewWillAppear:(BOOL)animated {

    [super viewWillAppear:animated];

    [self.navigationController setWantsFullScreenLayout:YES];
    [[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];    
}

请注意,为了清楚起见,我在这里设置了setWantsFullScreenLayout:YES,但实际上我只是在Interface Builder中设置了这个属性。

问题: NavigationController的导航栏不会向上移动以占用现在隐藏状态栏的空间。

一个hacky解决方案 我发现唯一能够刷新导航栏位置的方法是隐藏它并再次显示它,如下所示:

[[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];
[self.navigationController setNavigationBarHidden:YES animated:NO];
[self.navigationController setNavigationBarHidden:NO animated:NO];

但这显然是一个黑客,必须有一个更好的方法。

我试过的其他事情:

  1. 我在隐藏状态栏后尝试调用[super viewWillAppear],即在方法结束时。

  2. 我在navigationController.view上尝试了setNeedsLayout,如下所示:

    [[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];    
    [self.navigationController.view setNeedsLayout];
    
  3. 但这似乎不起作用。

    任何帮助表示赞赏。 感谢

4 个答案:

答案 0 :(得分:10)

有两种方法可以做你要求的事。

一种是手动移动导航栏:

在viewWillAppear中:

    [UIApplication sharedApplication].statusBarHidden = YES;
    self.view.frame = [UIScreen mainScreen].applicationFrame;
    CGRect frame = self.navigationController.navigationBar.frame;
    frame.origin.y = 0;
    self.navigationController.navigationBar.frame = frame;

在viewWillDisappear中:

    [UIApplication sharedApplication].statusBarHidden = NO;
    CGRect frame = self.navigationController.navigationBar.frame;
    frame.origin.y = 20.0;
    self.navigationController.navigationBar.frame = frame;

如果您愿意关闭导航栏,情况也会好转,虽然我怀疑这不是您想要的:

    [UIApplication sharedApplication].statusBarHidden = YES;
    self.navigationController.navigationBarHidden = YES;

答案 1 :(得分:2)

隐藏StatusBar后,您应该尝试调整UIViewControllers's视图的框架大小。 applicationFrame在setStatusBarHidden:animated:方法期间更新它的origin.y和size.height。

CGRect rect = [UIScreen mainScreen].applicationFrame;
self.view.frame = rect;

[self.view setNeedsLayout];

答案 2 :(得分:2)

我发现当视图位于动画演示文稿的中间时,上面的解决方案不能正常工作,因此我推迟隐藏状态栏,如下所示:

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    // doesn't work immediately because modal view has to finish loading
    dispatch_async(dispatch_get_main_queue(), ^(){
        [[UIApplication sharedApplication] setStatusBarHidden:YES];
        self.view.frame = [UIScreen mainScreen].applicationFrame;
    });
}

答案 3 :(得分:1)

在根视图控制器中(您要显示状态栏的位置):

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [[UIApplication sharedApplication] setStatusBarHidden:NO animated:YES];;
}

在视图控制器中,您可以按下堆栈(要隐藏状态栏的位置):

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];;
}

修改

我意识到你现在要隐藏状态栏。由于您在发布的代码中显示/隐藏导航栏,因此将它们混淆了。我的错。无论如何,它基本上是相同的代码:

在根视图控制器中(您要显示状态栏的位置):

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [[UIApplication sharedApplication] setStatusBarHidden:NO animated:YES];
}

在视图控制器中,您可以按下堆栈(要隐藏状态栏的位置):

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];
}

我刚刚使用现有项目对此进行了测试,但它确实有效。