为什么我必须在viewDidLoad中手动设置视图的框架?

时间:2011-07-20 04:29:12

标签: iphone ipad uiview frame viewdidload

我在UITabBarController中使用UINavigationController进行了非常基本的设置。我想以编程方式布局该navcontroller的rootViewController视图,但是当我查看viewDidLoad中的self.view.frame时,我得到了这个(例如 landscape ):

1. view frame: {{20, 0}, {748, 1024}} // looks like an odd portrait mode

然后我自动旋转到肖像,我明白了:

2. view frame: {{0, 0}, {768, 911}}

然后当我回到风景时,框架现在是这样的:

3. view frame: {{0, 0}, {1024, 655}}

进一步的自转事件将在帧值#2和&之间触发。 #3。

为了解决#1的奇怪现象,我目前正在viewDidLoad中这样做:

if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
    self.view.frame = CGRectMake(0, 0, 768, 911);
} else {
    self.view.frame = CGRectMake(0, 0, 1024, 655);
}

我觉得我在这里显然缺少一些东西。为什么视图的默认框架在自动旋转回相同方向时与框架不匹配?视图框架是否未设置为初始方向?很困惑......

我应该提到的是,上述所有内容,包括我的kludgy hack,都没有在视觉上改变任何东西。我有黑客的原因是,当我将我的子视图布局到这个视图中时,它们将基于我期望它们的位置,即导航栏下方的左上角。

我做错了什么?

更新:关闭视图上的所有自动调整内容,将结果#1更改为:

view frame: {{0, 0}, {748, 1024}}

这似乎有点接近,但仍然不匹配#3。

2 个答案:

答案 0 :(得分:98)

不保证viewDidLoad中的帧与最终显示视图时的帧相同。 UIKit会根据显示的上下文调整视图控制器视图的框架,然后再显示它。大小取决于界面方向和任何可见导航栏,标签栏,工具栏或状态栏的尺寸(其本身的高度可以更改,例如当您打电话时)。

有助于了解加载和显示视图控制器视图时会发生什么:

  1. Something第一次访问您的视图控制器的view属性。这可能发生在您自己的代码中,也可能发生在UIKit中,以响应用户操作,例如选择选项卡。

  2. UIKit通过调用loadView(如果已定义)或通过加载initWithNibName:bundle:中指定的NIB视图来延迟加载视图控制器的视图。如果两者都不存在,UIKit只会加载一个空视图。

  3. 一旦视图及其子视图完全加载,UIKit就会调用viewDidLoad 此时,视图的框架将是在NIB或loadView中设置的内容。

  4. 有人要求UIKit显示你的视图控制器的视图。同样,这可能是用户操作,例如点击标签,或者代码中的显式方法调用,例如pushViewController:animated:presentModalViewController:animated:

  5. 如上所述,UIKit会根据视图的上下文调整视图大小。

  6. UIKit调用viewWillAppear: 框架现在应该是将显示的尺寸。 (?)编辑:这可能不再是真的。请参阅以下评论。

  7. UIKit显示视图,有或没有动画。

  8. UIKit致电viewDidAppear:

  9. 正如您所看到的,如果您需要知道视图框架的大小,viewWillAppear:是您唯一的机会。请记住,视图出现后,由于各种原因(包括旋转事件或状态栏高度的更改),此大小可能会更改。因此,为每个子视图提供适当的autoresizingMask非常重要,以确保布局可以针对边界的任何更改进行适当调整。

    如果您希望手动构建视图层次结构,建议的位置是在loadView中。由于您在此方法中自己构建视图,因此可以将其框架初始化为您想要的任何内容。你选择的大小并不重要,因为无论如何UIKit很可能会改变它。只需确保正确设置autoresizingMasks。

答案 1 :(得分:-7)

你班上会有一个方法

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations    return YES; }

将你的框架放在这个方法中...然后它会正常工作。

例如:

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{
        // Return YES for supported orientations    
        if(interfaceOrientation == UIDeviceOrientationPortrait || UIDeviceOrientationPortraitUpsideDown)
                self.view.frame = CGRectMake(0, 0, FRAME.WIDTHinPOTRAIT, FRAME.HEIGHTinPOTRAIT);
        else if(interfaceOrientation == UIDeviceOrientationLandscapeRight || UIDeviceOrientationLandscapeLeft)
                self.view.frame = CGRectMake(0, 0, FRAME.WIDTHinLANDSCAPE, FRAME.HEIGHTinLANDSCAPE);

        return YES; 
}

FRAME.WIDTH>所需的宽度 FRAME.HEIGHT>所需高度