猿问

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

我在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相匹配。


慕容3067478
浏览 397回答 2
2回答

MYYA

不能保证在viewDidLoad中该框架与最终显示该视图时的框架相同。UIKit会在显示视图上下文之前,先调整视图控制器视图的框架。大小是根据界面方向和任何可见的导航栏,标签栏,工具栏或状态栏(其本身的高度可以更改,例如在通话中)的大小确定的。它有助于了解加载和显示视图控制器的视图时发生的情况:某些东西view首次访问了视图控制器的属性。这可能发生在您自己的代码中,也可能发生在UIKit中,以响应诸如选择选项卡之类的用户操作。UIKit通过调用(loadView如果已定义)或通过从中指定的NIB加载视图来延迟加载视图控制器的视图initWithNibName:bundle:。如果两者都不存在,则UIKit只会加载一个空视图。viewDidLoad一旦视图及其子视图已完全加载,UIKit就会调用。 此时,视图的框架将是在NIB或中设置的框架loadView。需要UIKit来显示视图控制器的视图。同样,这可能是用户操作,例如点击选项卡,或者是代码中的显式方法调用,例如pushViewController:animated:或presentModalViewController:animated:。如上所述,UIKit根据将在其中呈现的上下文调整视图的大小。UIKit调用viewWillAppear:。 现在,框架应为将要显示的尺寸。 (?)编辑:这可能不再正确。请参阅下面的评论。UIKit显示视图,带有或不带有动画。UIKit调用viewDidAppear:。如您所见,如果您需要在呈现视图之前知道视图框架的大小,则这viewWillAppear:是您唯一的机会。请记住,由于各种原因(包括旋转事件或状态栏高度的更改),视图出现后此大小可能会更改。因此,为每个子视图提供适当的autoresizingMask非常重要,以确保布局可以针对边界的任何更改进行适当调整。如果希望手动构建视图层次结构,建议在loadView中进行构建。由于您可以使用此方法自行构造视图,因此可以将其框架初始化为所需的任何形式。您选择的大小无关紧要,因为UIKit可能会在您身上进行更改。只要确保您正确设置了autoresizingMask。

凤凰求蛊

你班上会有一个方法- (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>所需高度
随时随地看视频慕课网APP

相关分类

iOS
我要回答