为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

iOS
慕容3067478 2019-10-16 14:23:44
我在UITabBarController内部使用UINavigationController进行了非常基本的设置。我想以编程方式布局该navcontroller的rootViewController的视图,但是当我查看viewDidLoad内的self.view.frame时,我得到了这一点(例如,在landscape中):1. view frame: {{20, 0}, {748, 1024}} // looks like an odd portrait mode然后我自动旋转到Portrait,我得到了: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);}我觉得我显然在这里缺少什么。当视图的默认框架自动旋转回相同方向时,为什么它与该框架不匹配?视框是否未设置为初始方向?很迷茫...我应该提到的是,以上所有内容(包括我的糊涂技巧)都无法在视觉上进行任何更改。我受到黑客攻击的原因是,当我将子视图布局到该视图中时,它们将基于我期望的位置,即导航栏下方的左上角。我究竟做错了什么?更新:关闭视图上的所有自动调整大小的东西会将结果#1更改为:view frame: {{0, 0}, {748, 1024}}这似乎有点接近,但仍无法与#3相匹配。
查看完整描述

2 回答

?
MYYA

TA贡献1868条经验 获得超4个赞

不能保证在viewDidLoad中该框架与最终显示该视图时的框架相同。UIKit会在显示视图上下文之前,先调整视图控制器视图的框架。大小是根据界面方向和任何可见的导航栏,标签栏,工具栏或状态栏(其本身的高度可以更改,例如在通话中)的大小确定的。

它有助于了解加载和显示视图控制器的视图时发生的情况:

  1. 某些东西view首次访问了视图控制器的属性。这可能发生在您自己的代码中,也可能发生在UIKit中,以响应诸如选择选项卡之类的用户操作。

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

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

  4. 需要UIKit来显示视图控制器的视图。同样,这可能是用户操作,例如点击选项卡,或者是代码中的显式方法调用,例如pushViewController:animated:presentModalViewController:animated:

  5. 如上所述,UIKit根据将在其中呈现的上下文调整视图的大小。

  6. UIKit调用viewWillAppear:。 现在,框架应为将要显示的尺寸。 (?)编辑:这可能不再正确。请参阅下面的评论。

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

  8. UIKit调用viewDidAppear:

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

如果希望手动构建视图层次结构,建议在loadView中进行构建。由于您可以使用此方法自行构造视图,因此可以将其框架初始化为所需的任何形式。您选择的大小无关紧要,因为UIKit可能会在您身上进行更改。只要确保您正确设置了autoresizingMask。


查看完整回答
反对 回复 2019-10-16
?
凤凰求蛊

TA贡献1825条经验 获得超4个赞

你班上会有一个方法


- (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>所需高度


查看完整回答
反对 回复 2019-10-16
  • 2 回答
  • 0 关注
  • 360 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信