【问题标题】:UINavigationController within ViewController, gap at top of viewViewController 中的 UINavigationController,视图顶部的间隙
【发布时间】:2011-07-08 05:12:41
【问题描述】:

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

一切都很好,除了视图的布局。当应用以纵向模式启动时,所有功能都会在设备方向发生变化时正确调整大小/位置。

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

【问题讨论】:

  • 为什么不把每次旋转的帧调整为self.view.frame.size.height?
  • @sudo - 是的,我已经这样做了,这有帮助......但前提是设备旋转!如果应用程序以纵向以外的任何方向启动(按下按钮),它看起来就像最后一个屏幕截图。我没有尝试过任何调整来消除差距。
  • 他们尝试将其设置为[[UIScreen mainScreen] bounds].size.height?
  • 围绕这个话题有很多问题,没有正确答案:/
  • 您是如何在标签栏中放置彩色图标的?我曾尝试在我的应用程序中执行此操作,但我将 UIImageView 放在栏上。

标签: iphone xcode ipad ios interface-builder


【解决方案1】:

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

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

【讨论】:

  • 这对我有用,我强烈推荐这个解决方案而不是其他 -20 像素黑客。
  • 很棒的破解^H^H^H^Hsolution :)
  • 不幸的是,在 iOS 6 中对我不起作用。20px hack 确实有效。
【解决方案2】:

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

- (BOOL)wantsFullScreenLayout {
    return NO;
}

在我的故事板中取消选中“想要全屏”并没有解决问题,所以我不知道有什么不同。这肯定会在未来的 iOS 版本中中断。但现在,我会接受它。

【讨论】:

  • 是的,这真的很奇怪,当我在 iOS 6 中将导航控制器设置为关键窗口的 rootViewController 时,即使我将其设置为 NO,它的 WantFullScreenLayout 也始终为 YES。这篇文章解决了我的问题,谢谢!但在 iOS 5 中,设置为 NO 后该值为 NO。这可能是苹果的错误吗?
  • 我已经为此问题进行了颠倒搜索。最后这个解决了我。
  • 我使用了一个视图控制器可见的类别,该类别用作导航控制器的容器。
  • @FábioOliveira 请记住,您的小类别将应用于您应用中的每个导航控制器,甚至是系统提供的导航控制器。 (例如,邮件撰写控制器或照片选择器将受到影响。)这可能不是最好的主意!
  • @BrentRoyal-Gordon,我有一个视图控制器,它是我自己实现的模态视图控制器容器。该类别仅包含在该类别中。这如何适用于每个导航控制器?我实际上刚刚检查过,你是对的。怎么样?
【解决方案3】:

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

解决方案是将 UINavigationController 上的 wantsFullScreenLayout 设置为 NO,因此它甚至不会尝试为状态栏留出空隙。

【讨论】:

  • 谢谢,但这并没有什么不同。
【解决方案4】:

我能够暴力破解如下。在viewDidLoad 或loadView:

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);
}

这很丑,但它似乎工作。

【讨论】:

    【解决方案5】:

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

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

    正如苹果文档所说:

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

    【讨论】:

      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

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

        来自 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 的视图会从屏幕上移出 20 个像素到顶部,那么您将已根据初始方向动态设置控制器的wantsFullScreenLayout 属性(而不是上述解决方案)。 我使用导航控制器实现中定义的静态变量来完成它:

        static UIInterfaceOrientation _initialOrientation = -1;
        

        之后你需要重载viewDidAppear:方法并适当地设置变量:

        - (void)viewDidAppear:(BOOL)animated
        {
          if (_initialOrientation == -1)
            _initialOrientation = [[UIApplication sharedApplication] statusBarOrientation];
          self.wantsFullScreenLayout = (_initialOrientation != UIInterfaceOrientationPortrait);
        
          [super viewDidAppear:animated];
        }
        

        希望这会有所帮助。

        【讨论】:

          【解决方案8】:

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

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

          【讨论】:

            【解决方案9】:

            在状态栏和视图直接below 之间存在类似的问题,通过在界面生成器中转到autosizing 并将相关视图设置为坚持其父视图的顶部来解决它.

            【讨论】:

              【解决方案10】:

              在导航控制器中显示的视图中,我将此代码放在 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
              

              【讨论】:

                【解决方案11】:

                正确答案是:

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

                【讨论】:

                  猜你喜欢
                  • 2016-01-23
                  • 2012-02-11
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多