包含 UINavigationController 的状态栏大小不正确

Posted

技术标签:

【中文标题】包含 UINavigationController 的状态栏大小不正确【英文标题】:Status bar sized incorrectly with a contained UINavigationController 【发布时间】:2015-07-31 12:02:34 【问题描述】:

我通过 containment 使 UINavigationController 成为另一个视图控制器的子节点。一切正常,除了在打开 通话状态栏 的情况下启动应用程序,然后在应用程序 UI 显示在屏幕上后将其切换回关闭时发生的一个奇怪问题。出现奇怪的黑色差距来代替状态栏。

请考虑下面的自包含示例应用程序:

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

@implementation AppDelegate
- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)opt

  // Content
  UILabel * aLbl = [[UILabel alloc] initWithFrame:CGRectMake(20, 100, 200, 40)];
  aLbl.text = @"In-call status bar issue";

  UIViewController * aContent = [[UIViewController alloc] init];
  aContent.title = @"Title";
  aContent.view.backgroundColor = UIColor.whiteColor;
  [aContent.view addSubview:aLbl];

  UINavigationController * aNav = [[UINavigationController alloc]
    initWithRootViewController:aContent];

  // Parentmost view controller containing the navigation view controller
  UIViewController * aParent = [[UIViewController alloc] init];
  [aParent.view addSubview:aNav.view];
  [aParent addChildViewController:aNav];
  [aNav didMoveToParentViewController:aParent];

  self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
  self.window.rootViewController = aParent;
  [self.window makeKeyAndVisible];

  return YES;

@end

int main(int argc, char ** argv)
   @autoreleasepool  return UIApplicationMain(argc, argv, nil, @"AppDelegate");  

重现问题的最简单方法是:

    启动 ios 模拟器。 按⌘+ y打开呼叫状态栏。状态栏会变宽和绿色。 手动启动应用程序并等待导航控制器出现。 再次按⌘+ y关闭呼叫状态栏。

用户界面现在应该如下所示:

任何人都知道如何解决问题?

【问题讨论】:

您是否尝试将尺寸等级或自动调整大小的掩码设置为UINavigationContorller 的视图?因为您的应用程序的UIWindow 的大小调整应该是开箱即用的。所以我怀疑问题出在导航控制器的UIView 上。 我能够重现 OP 所描述的问题。在应用程序启动后切换通话状态栏会导致预期的行为,但如果应用程序在通话状态栏打开后启动,则关闭通话状态栏将导致黑条。 我也刚在iOS设备上试了一下,问题又重现了,所以好像不是模拟器特有的。 @akivajgordon:不,这绝对不是模拟器特有的。我提到模拟器只是因为它是重现问题的最简单方法。 非常好的问题。根据您的指示,我很容易重现了这种现象。如果只有每个人都会以这种方式提问! span> 【参考方案1】:

您正在将一个视图(导航控制器的视图)作为子视图添加到另一个视图(父视图控制器的视图),而不给它一个框架!这是你应该绝不做的事情。

只需将这些行添加到您的代码中:

aNav.view.frame = aParent.view.bounds;
aNav.view.autoresizingMask = 
    UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;

现在导航控制器的视图有一个框架,并保持它与其父视图的关系。

【讨论】:

第二行并不是完全必要的,只是为了解决你提出的问题,但显然你不仅需要一个大小,而且还需要一个规则来调整超级视图的大小。在现实生活中,我可能会使用约束而不是 autoresizingMask,但我想保持简短。 并查看我的书,了解当您执行自定义父视图控制器并添加子视图控制器并添加子视图时必须执行的舞蹈的完整详细信息:apeth.com/iOSBook/ch19.html#_container_view_controllers 您按错误的顺序执行这些步骤(虽然我怀疑这是否会影响这个特定问题)。 谢谢哥们!你让我今天一整天都感觉很好!既简单又精彩! 你得到了很多功劳。正如我之前所说,你把问题准备得非常好。您将其缩减为重现问题所需的最小情况,并提供了重现问题的代码和说明。我希望每个人都这样问问题! 整天都在寻找这个答案!非常感谢!

以上是关于包含 UINavigationController 的状态栏大小不正确的主要内容,如果未能解决你的问题,请参考以下文章

包含 UINavigationController 的状态栏大小不正确

UINavigationController 包含一个 UITableView,然后是一个包含更多 UITableView 的 UITabBarController

UINavigationController 包含、iOS7 和状态栏。漏洞?

UINavigationController 嵌套在 moreViewController 中的问题

UINavigationController '菜单'

将 UINavigationController 添加到标签栏应用程序