这是我在这里遇到的问题(仍未解决)的延续:link
但这可能有助于了解问题所在。 我只创建了一个简单的测试项目('Empty Application')并添加了一个带有XIB文件的视图控制器(复选框:'选择了用户界面的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模拟器上测试)
答案 0 :(得分:3)
当调用viewDidLoad
方法时,您的视图控制器刚从故事板或XIB加载,因此视图尺寸等于XIB中的视图尺寸(看起来像iPhone 5高度)尺寸)。
稍后,当调用viewDidAppear:
时,视图已经出现在屏幕上,因此它已经适当调整大小以实际适合屏幕,因此其尺寸可能与故事板中的尺寸不同,因此与加载视图时设置的不同。
在您的情况下,看起来您的故事板或XIB文件设置为iPhone 5屏幕大小(548 = 1136/2 - 状态栏),并且您正在使用480x320点的iPhone 5之前的模拟器或设备进行测试屏幕,因此视图可以调整大小到460点高,以适应屏幕。
答案 1 :(得分:1)
这可能有完美的感觉。
首次访问ViewDidLoad
时, controller.view
会被懒惰地调用,所以此时框架尚未设置。这意味着此时您不能依赖于帧/边界大小,因为它只包含一个默认值(尽管在许多情况下它是正确的)。
在ViewDidAppear
中,帧通常是设置的,但是如果你的父控制器正在设置任何动画,你也可以有一个时间帧状态而不是最后一个,但是按照惯例,这种方法通常不会被调用。视图已经显示。
例如,如果您从IB文件加载视图,那么您将在viewDidLoad
中获得的框架是您在IB文件中获得的框架,但您的视图的最终尺寸可能更小/更大,然后你会在viewDidAppear
中获得另一个。
而不是那样,你应该创建所有可调整大小的元素(使用Spring& Struts,AutoLayout或任何其他类似的替代方案),以便在设置框架时正确显示它们。
答案 2 :(得分:0)
当
ViewController
显示其视图时,通常会缩小该视图 查看,使其框架不与设备的状态栏重叠。
因此,当您NSLog
viewDidLoad
时,视图i尚未加载,因此ViewController
尚未缩小框架,但在viewDidAppear
中,它已完成大小调整。
UIViewController
中有一处房产
wantsFullScreenLayout
将此属性设置为YES会导致视图控制器调整其大小 查看,以便它填满整个屏幕,包括下面的区域 状态栏。 (当然,为了实现这一点,托管的窗口 视图控制器本身的大小必须足以填满整个屏幕, 包括状态栏下方的区域。)您通常会设置 如果您有半透明状态栏,则此属性为YES 并希望您的视图内容在该视图后面可见。
答案 3 :(得分:0)
据我所知,ViewDidLoad将根据定义设置应用程序的边界,在根视图的RootViewController / XIB文件中,或者可能是AppDelegate。
如果您在那里定义应用程序边界(不确定其中哪一个),整个应用程序中的ViewDidLoad函数最初将根据该值设置高度。
加载视图并准备“出现”后,可能会请求实际边界。 因此,建议在ViewWillAppear / ViewDidAppear方法中请求边界/大小。
答案 4 :(得分:0)
-viewDidLoad
在第一次调用viewController.view
时调用。在返回视图之前调用它。这具有非常重要的意义。为了显示或调整视图,需要将其添加到窗口或其他视图中。
这是怎么发生的?它看起来像[window addSubview:viewController.view]
。
因此,在将视图放入视图层次结构之前,需要满载视图。在self.view
中使用时,这会对-viewDidLoad
造成限制。
self.view.superview
和self.view.window
始终为nil
。self.view
尚未调整为适合self.view.superview
。根据这种理解,您可以看到self.view
在调用-viewDidLoad
时无法知道它的最终大小。
<强>更新强>
如果您需要将自定义布局应用于视图的子视图,您可能需要考虑将UIView
子类化并使用-[UIView layoutSubviews]
。
除非您在使用-viewWillAppear:
而不是-viewDidAppear:
时遇到问题?在显示视图之前调用-viewWillAppear:
,因此在调整视图大小时不会产生奇怪的视觉效果。