正确的loadView实现

Ada*_*dam 14 uiviewcontroller uiview ios

Apple的文档没有说明loadView的正确实现.

我发现如果你像这样实现loadView:

- (void)loadView
{
    self.view = [[UIView alloc] init];
}
Run Code Online (Sandbox Code Playgroud)

...然后你会得到不同的行为,而不是你根本没有实现它.特别是,在一个20行的项目中,我发现viewWillAppear被调用为self.view的零大小框架 - 除非你使用Apple的默认版本的loadView.

在Google上看,有很多"教程"提供了明显错误的loadView实现 - 例如强制设置大小为(320,480),因为教程作者"发现它可行,如果我这样做".

我想知道正确的实现应该是什么.

注意:在上面的例子中,我将它添加到AppDelegate中的视图层次结构中,如下所示:

[self.window addSubview:(UIViewController*).view];
Run Code Online (Sandbox Code Playgroud)

我相信,在存在UINavigationController或UITabBarController的情况下,Apple会做一些额外的魔术 - 作为副作用 - 导致单行loadView实现正常工作.但是我想写得正确,所以它总能奏效!

注意:我已尝试在根视图上设置自动调整掩码,但它不会改变发生的情况:

- (void)loadView
{
    self.view = [[UIView alloc] init];
    self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
}
Run Code Online (Sandbox Code Playgroud)

Tri*_*ops 15

默认实现-loadView 创建视图或加载NIB.据我所知,目前还没有办法知道该视图的最终大小在创建的时候-loadView.因此默认视图大小设置为UIScreen.mainScreen.bounds.这是因为在-viewDidLoad其他方法中使用零帧视图可能很困难.

您的单行实现可能如下所示:

- (void)loadView {
    self.view = [[UIView alloc] initWithFrame:UIScreen.mainScreen.bounds];
}
Run Code Online (Sandbox Code Playgroud)

您不需要设置自动调整遮罩,因为您不知道视图将在何种上下文中显示.调用者负责设置正确的帧,自动调整掩码和类似属性.

想象一下这个UINavigationController方法:

// we are pushing new VC, view is accessed for the first time
pushedVC.view.frame = CGRectMake(...);
Run Code Online (Sandbox Code Playgroud)

它正在设置正确的帧,但之前-loadView调用它.因此,在您拥有临时非零帧时,只需设置子视图和内部自动调整即可.在此之后,将为您设置正确的帧,并且您拥有最终帧.-setFrame:-viewDidLoad-viewWillAppear:


Aar*_*man 13

首先,没有"默认"实现loadView...该方法专门用于覆盖.我确实同意Apple的文档可能有点不清楚.但是loadView,只要访问导航控制器的视图并且不存在视图(例如:),就会默认调用UIView *view = viewController.view.它也可以手动调用.但在任何情况下都不loadView会有正确的尺寸......事实上,这是不可能的. loadView调用,以便父视图控制器首先获取视图,以便它可以适当地调整大小.然后一旦它获得它所调用的视图viewDidLoad.这是他们可以使用的唯一代码路径,因为视图可以从loadView方法或nib加载,并且当从nib加载视图时,它们必须提供额外设置的位置.最后,父控制器将调整视图的大小,并viewWillAppear仅在实际显示视图时调用.例如,如果你在一个离开屏幕的navController上按下一个控制器,它就不会调用,viewWillAppear直到navController本身放在屏幕上.这样做是因为在控制器实际可见之前运行该代码毫无意义.这也是您只能在viewWillAppear方法中获得正确尺寸的原因.

现在,您注意到如果将控制器添加到标准控制器,则不会发生这种情况.这是因为视图控制器实际上并不打算包含其他视图控制器.现在在iOS 5中,他们明确支持使用容器视图控制器......它本质上是一个视图控制器,旨在包含其他视图控制器.他们在iOS 5中添加了一些"便利"方法来帮助解决这个问题,但这并不是绝对必要的.所有这些的要点是:如果要将一个视图控制器添加到另一个视图控制器,则必须手动设置对子视图控制器的所有适当调用(所有加载方法,旋转事件,内存警告等).换句话说,您必须创建自己的容器视图控制器.但是,当你这样做时,请记住我之前所说的关于代码路径的内容.重要的是,您按照Apple所做的相同顺序调用子控制器方法,否则这些方法将无法正常工作.

以下是一些信息链接:http: //developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html- 向下滚动到:实现容器视图控制器

此处还有视图控制器生命周期,它将帮助您确定需要按顺序进行哪些调用:http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/ViewLoadingandUnloading/ViewLoadingandUnloading.html# // apple_ref/DOC/UID/TP40007457-CH10-SW1

我建议您阅读整个View Controller编程指南....您可以从那里获得大量信息:http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/Introduction/Introduction.html#//apple_ref/DOC/UID/TP40007457-CH1-SW1

  • 不,那是不正确的。请仔细阅读问题。如果我*不*实现它,那么我会得到一个非零帧。如果我“创建”它,那么我会得到零帧。 (2认同)