查看高度问题(续)
这是对我在这里(这仍然是未解决)的问题的继续: 链接
但是这可能有助于了解问题所在。 我创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.view
, ViewDidLoad
被懒惰地调用,所以到那时帧还没有被设置。 这意味着你不能依赖帧/边界的大小,因为它只包含一个默认值(尽pipe在很多情况下它是正确的)。 在ViewDidAppear
,框架通常被设置,虽然如果你的父控制器设置任何animation,你也可以有一个临时的框架状态,而不是最终的框架状态,但是通常这个方法在视图已经被显示时调用。
例如,如果您正在从IB文件加载视图,您将在viewDidLoad
获得的框架是您在IB文件中的框架,但是您的视图的最终大小可能会更小/更大,然后您将获得另一个在你的viewDidAppear
。
相反, 你应该创build所有的元素可resize (使用Spring&Struts,AutoLayout或任何其他类似的替代),以便在设置框架时正确显示它们。
当
ViewController
显示其视图时,通常会缩小该视图,使其框架不与设备的状态栏重叠。
所以当你在NSLog
中viewDidLoad
,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
。
-
self.view.superview
和self.view.window
将始终nil
。 -
self.view
还没有适合self.view.superview
大小。
有了这个理解,你可以看到-viewDidLoad
在调用-viewDidLoad
时候无法知道它的最终大小。
UPDATE
如果您需要将自定义布局应用于视图的子视图,则可能需要考虑对UIView
进行子类化并使用-[UIView layoutSubviews]
。
除了这个,你是否有麻烦-viewWillAppear:
而不是-viewDidAppear:
-viewWillAppear:
在显示视图之前调用,因此在调整视图的大小时不会有奇怪的视觉效果。