ViewController中的UINavigationController,视图顶部的间隙

时间:2011-03-03 16:52:19

标签: iphone xcode ipad ios interface-builder

我正在开发一款通用应用,我正试图在iPhone和iPad版本之间共享尽可能多的代码。我需要使用TabBarController作为我的根视图控制器,虽然我想在每个选项卡中使用SplitViewController,但SplitViewController的文档说它需要是根视图控制器。因此,考虑到所有这些 - 了解我正在尝试并排放置两个导航控制器,并且(大部分)复制SplitViewController的行为/布局。

除了视图的布局外,一切正常。当应用程序以纵向模式启动时,一切都会在设备方向改变时正常运行并调整大小/位置。

portrait orientation

如果应用程序以UIDeviceOrientationPortrait以外的任何方向启动,则视图将在导航控制器上方显示20点间隙/边距。我试过在运行时调整帧没有完美的结果。将框架的origin.y调整为-20并将高度增加20会使视图与其父级的顶部齐平,但在底部留下20个点的间隙!

landscape orientation

11 个答案:

答案 0 :(得分:25)

我在我的应用程序中通过隐藏然后在添加导航控制器视图后显示导航栏来解决这个问题。例如

[parentView addSubview:navController.view];
[navController setNavigationBarHidden:YES];
[navController setNavigationBarHidden:NO];

答案 1 :(得分:16)

奇怪的是,在iOS 6中对我有帮助的是继承UINavigationController并实现这个方法:

- (BOOL)wantsFullScreenLayout {
    return NO;
}

在我的故事板中取消选中“想要全屏”并没有做到这一点,所以我不知道有什么不同。这肯定会在iOS的未来版本中破裂。但就目前而言,我会接受它。

答案 2 :(得分:3)

UINavigationController通常显示为全屏控制器,这意味着(当显示为窗口的根视图控制器时)其视图的顶部位于状态栏下方。然后,当状态栏可见时,它会手动将其导航栏和内容视图定位到 not 不足状态栏。不幸的是,当它被某个其他视图控制器定位时,它并没有真正正确地处理事情,它(有时)假设它需要保留它的20px间隙而不检查它的视图实际上是否

解决方法是将UINavigationController上的wantsFullScreenLayout设置为NO,这样它甚至不会尝试为状态栏留下那个间隙。

答案 3 :(得分:3)

我能够蛮力如下。在viewDidLoadloadView

if (self.navigationController.navigationBar.frame.origin.y > 0.0) {
    self.navigationController.navigationBar.frame = CGRectOffset(self.navigationController.navigationBar.frame, 0.0, -20.0);
}

在viewDidAppear中:

if (self.view.superview.frame.origin.y > 44.0) {
    UIView *container = self.view.superview;
    container.frame = CGRectMake(container.frame.origin.x, container.frame.origin.y - 20.0, container.frame.size.width, container.frame.size.height + 20.0);
}

这很难看,但似乎有效。

答案 4 :(得分:3)

要解决此问题,只需选中情节提要上的Wants Full Screen框。

出现问题是因为ParentViewController显示了导航栏。

正如苹果文档所说:

如果您的应用显示状态栏,则视图会缩小,以便不会覆盖状态栏。毕竟,如果状态栏不透明,则无法查看或与其下方的内容进行交互。但是,如果您的应用程序显示半透明状态栏,则可以将视图控制器的wantsFullScreenLayout属性的值设置为YES,以允许您的视图全屏显示。状态栏位于视图顶部。

答案 5 :(得分:2)

不确定它是否会有任何帮助,但过去我遇到过类似的问题,并且能够通过在将UINavigationController视图添加到超级视图时将其设置为CGRectZero来解决此问题。

在layoutSubviews中,我当然会更新UINavigationController视图的框架。

答案 6 :(得分:2)

将视图控制器添加到标签栏时,这是一个常见问题。

来自Apple的文档(Tab Bar Controllers - Tab Bars and Full-Screen Layout):

  

标签栏控制器支持全屏布局,与大多数其他控制器支持的方式不同。如果希望其视图覆盖状态栏或导航栏(如果存在),则仍可以将自定义视图控制器的wantsFullScreenLayout属性设置为YES。但是,将此属性设置为YES不会导致视图覆盖标签栏视图。选项卡栏控制器始终调整视图大小以防止其重叠标签栏。

在代码中,您应该执行以下操作:

UINavigationController *myNavController = [[UINavigationView alloc] init];
myNavController.wantsFullScreenLayout = YES;

//...

NSArray* controllers = [NSArray arrayWithObjects:myNavController, nil];
myTabBarController.viewControllers = controllers;

如果,然而,则会遇到以下问题:在UIInterfaceOrientationPortrait myNavController以外的方向打开应用程序时,您的wantsFullScreenLayout视图会将屏幕上的20个像素移到顶部,然后您将动态设置控制器的static UIInterfaceOrientation _initialOrientation = -1; 属性(而不是上述解决方案),具体取决于初始方向。 我使用导航控制器实现中定义的静态变量来做到这一点:

viewDidAppear:

之后你需要重载- (void)viewDidAppear:(BOOL)animated { if (_initialOrientation == -1) _initialOrientation = [[UIApplication sharedApplication] statusBarOrientation]; self.wantsFullScreenLayout = (_initialOrientation != UIInterfaceOrientationPortrait); [super viewDidAppear:animated]; } 方法并适当地设置变量:

{{1}}

希望这有帮助。

答案 7 :(得分:2)

在viewDidLoad上向我的ViewController添加UITableView时遇到了同样的问题。我没有从self.view中抓取框架,而是将其从主窗口中获取,使其看起来像这样

UIWindow *keyWindow = [[[UIApplication sharedApplication] delegate] window];
self.uiTable = [[UITableView alloc] initWithFrame:[keyWindow frame] style:UITableViewStylePlain];

答案 8 :(得分:0)

状态栏和视图之间的不必要差距直接below有类似问题,通过转到界面构建器中的autosizing并将相关视图设置为顶部来解决问题其父视图。

答案 9 :(得分:0)

在我的视图中显示在navigationcontroller中我将此代码放在viewDidAppear中

这段代码可能并不适用于所有应用程序,但它修复了我的问题,我花了几个小时来踢...

    // START OF BUG FIX FOR iOS
if (self.navigationController.navigationBar.frame.origin.y ==20) {
    // Move the navigation Bar up
    [self.navigationController.navigationBar setFrame:CGRectMake(0, 0, self.navigationController.navigationBar.frame.size.width, self.navigationController.navigationBar.frame.size.height)];
    // move up the table view
     [self.view setFrame:CGRectMake(0, -20, self.view.frame.size.width, self.view.frame.size.height+20)];
}
// END OF BUG FIX for IOS6

答案 10 :(得分:-1)

正确的答案是:

CGRect r = [[_navController view] frame];
r.origin = CGPointMake(0.0f, -20.0f);
[[_navController view] setFrame:r];