查看高度问题(续)

这是对我在这里(这仍然是未解决)的问题的继续: 链接

但是这可能有助于了解问题所在。 我创build了一个简单的testing项目('空应用程序'),并添加了一个视图控制器与XIB文件(checkbox:'用XIB文件的用户界面'选中)。 代码如下所示:

- (void)viewDidLoad { [super viewDidLoad]; NSLog(@"didLoad: %@",NSStringFromCGRect(self.view.bounds)); // Do any additional setup after loading the view from its nib. } -(void) viewDidAppear:(BOOL)animated { NSLog(@"didAppear: %@",NSStringFromCGRect(self.view.bounds)); } 

这是输出:

 2013-07-26 17:05:28.502 testtest[5926:c07] didLoad: {{0, 0}, {320, 548}} 2013-07-26 17:05:28.506 testtest[5926:c07] didAppear: {{0, 0}, {320, 460}} 

他们怎么不一样?

(ps。我在6.1模拟器上testing)

viewDidLoad方法被调用时,你的视图控制器只是刚刚从你的故事板或XIB加载,所以视图尺寸等于你在XIB(那些看起来像iPhone 5的高度尺寸)。

后来,当viewDidAppear:被调用的时候,视图已经出现在屏幕上,所以已经适当resize以适应屏幕,所以它的尺寸可能与故事板中的尺寸不同,因此与设置的不同当视图被加载时。

在你的情况下,它看起来像故事板或XIB文件被设置为iPhone 5的屏幕大小(548 = 1136/2 – 状态栏),并且你正在一个前iPhone 5模拟器或480×320点屏幕设备testing视图被调整到高达460点以适合屏幕。

这可能有完美的意义。

当第一次访问controller.viewViewDidLoad被懒惰地调用,所以到那时帧还没有被设置。 这意味着你不能依赖帧/边界的大小,因为它只包含一个默认值(尽pipe在很多情况下它是正确的)。 在ViewDidAppear ,框架通常被设置,虽然如果你的父控制器设置任何animation,你也可以有一个临时的框架状态,而不是最终的框架状态,但是通常这个方法在视图已经被显示时调用。

例如,如果您正在从IB文件加载视图,您将在viewDidLoad获得的框架是您在IB文件中的框架,但是您的视图的最终大小可能会更小/更大,然后您将获得另一个在你的viewDidAppear

相反, 你应该创build所有的元素可resize (使用Spring&Struts,AutoLayout或任何其他类似的替代),以便在设置框架时正确显示它们。

ViewController显示其视图时,通常会缩小该视图,使其框架不与设备的状态栏重叠。

所以当你在NSLogviewDidLoad ,View还没有加载,所以ViewController还没有缩小帧但是在viewDidAppear ,它已经做了大小调整。 UIViewController有一个属性
wantsFullScreenLayout

将此属性设置为YES会导致视图控制器调整其视图的大小,使其填充整个屏幕,包括状态栏下的区域。 (当然,发生这种情况时,托pipe视图控制器的窗口本身的大小必须能够填充整个屏幕,包括状态栏下方的区域。)通常,在具有半透明状态的情况下,将此属性设置为YES酒吧,并希望您的视图的内容在该视图后面可见。

据我所知,ViewDidLoad将为您的应用程序设置界限,在根视图的RootViewController / XIB文件中,或者可能是AppDelegate。

如果你定义了应用程序边界(不知道在哪一个),ViewDidLoad函数在整个应用程序,最初将根据该设置高度。

一旦视图被加载,并准备好“出现”,可能会要求实际边界。 因此build议在ViewWillAppear / ViewDidAppear方法中请求边界/大小。

-viewDidLoad被称为第一次viewController.view被调用。 它在视图返回之前被调用。 这具有非常重要的意义。 为了显示或调整视图,需要将其添加到窗口或其他视图中。

这是怎么发生的? 它看起来像[window addSubview:viewController.view]

因此,在将其放入视图层次结构之前,需要完全加载的视图。 在-viewDidLoad使用时,这会限制-viewDidLoad

  1. self.view.superviewself.view.window将始终nil
  2. self.view还没有适合self.view.superview大小。

有了这个理解,你可以看到-viewDidLoad在调用-viewDidLoad时候无法知道它的最终大小。


UPDATE

如果您需要将自定义布局应用于视图的子视图,则可能需要考虑对UIView进行子类化并使用-[UIView layoutSubviews]

除了这个,你是否有麻烦-viewWillAppear:而不是-viewDidAppear: -viewWillAppear:在显示视图之前调用,因此在调整视图的大小时不会有奇怪的视觉效果。