28

摘要:在初始化那个视图时应该如何UIViewController知道它的 UIView 实例的大小?

UIView 的专用初始化方法是initWithFrame:(CGRect)frame方法。这将为新创建的 UIView 设置框架。UIViewController's如果请求视图控制器的视图,则可以从 loadView 方法调用此方法。UIViewController关于子类化和视图大小的状态文档:

在为视图层次结构创建视图时,您应该始终设置视图的自动调整大小属性。当视图控制器显示在屏幕上时,它的根视图通常会调整大小以适应可用空间,这可能会根据窗口的当前方向和其他界面元素(例如状态栏)的存在而有所不同。

因此,UIViewController实例应该设置这些属性。到目前为止这么好,UIViewController到目前为止不必知道它的观点有多大或将有多大。

UIViewController请求 a 的视图且视图属性为 nil 时,调用视图控制器的 loadView 方法。现在有一个问题,因为UIView需要初始化,但是视图控制器仍然不知道视图应该是什么大小。你应该初始化多大的视图?您在代码中的哪个位置确定视图大小?

您可以使用零矩形 ( CGRectZero) 初始化视图:

- (void)loadView {
    self.view = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
}

让调用者像这样设置视图框架:

UIViewController *viewController = [[MyUIViewController alloc] init];
// next two lines are normally combined, but for clarity they are not now
UIView *view = viewController.view;
view.frame = CGRectMake(0, 0, 200, 200);

这会从视图控制器 (viewController.view) 请求视图,从而使用 loadView 方法加载其视图。此 loadView 方法使用CGRectZero. 然后调用者设置它的框架(view.frame = ...)

问题是视图上的 frame 属性设置了两次,如果您的自定义UIView在 setFrame 方法中进行一些高级布局(例如放置和调整子视图大小),可能会导致更多的工作。您可以通过创建一个专用的初始化方法来防止这种情况,该方法UIViewController已经向调用者询问了一个 CGRect,您将其存储在一个 ivar 中。在调用 loadView 方法时,您使用此 ivar 创建视图。

去这里的好方法是什么?设置视图的框架两次(用 初始化CGRectZero,然后设置),或者给UIViewController一个新的初始化方法和一个 CGRect (从而给它一个框架属性)?或者我错过了什么,还有其他可能性吗?

4

3 回答 3

8

您不必使用指定的初始化程序。只需像 in 一样使用 init [[UIView alloc] init]。指定的初始化器必须从子类的初始化器中使用。

另一方面,将框架设置两次应该不会造成太大的伤害。执行大量任务setFrame:是不寻常的。布局通常在其中完成layoutSubviews并且只执行一次。

于 2009-07-09T11:35:11.690 回答
0

在从 UIViewController 子类化以创建通用组件后,我目前正在尝试完成同样的事情,并注意到一些非常奇怪的事情:

UIViewController 有一个“loadView”方法,您可以覆盖它(引用文档)“这是子类应该创建其自定义视图层次结构的地方”。

因此,我创建了我的视图层次结构,使用默认帧大小合成我的屏幕(因为我可能不知道在调用 loadView 时我应该将内容显示到的帧)。

但是,在什么情况下我可以正确设置帧大小?又名:我的视图控制器什么时候知道它的视图实际大小?

我是否必须在我的 ViewController 子类中创建一个创建 viewcontroller 的对象应该调用的“setFrame”?这似乎很奇怪。

drvdijk:你有解决问题的方法吗?

编辑:刚刚在 UIViewController 文档上找到了这个注释:注意:您不应该使用视图控制器来管理仅填充其窗口的一部分的视图 - 即仅由应用程序内容矩形定义的区域的一部分。如果您想要一个由多个较小视图组成的界面,请将它们全部嵌入到一个根视图中,并使用您的视图控制器管理该视图。

所以,似乎 UIViewController 主视图总是全屏的。时期。

不过,这确实给我带来了一个问题,因为我正在尝试创建一个自定义 UITabBarViewController(以便能够在标签栏中显示自定义图像,而不是蓝色渐变):我的 tabBarViewController 应该仅将子视图控制器显示到窗口的一部分中。 ..

于 2009-12-23T18:06:11.113 回答
0

您可能想要计算可用屏幕空间的界限(这取决于是否存在其他视图,如导航栏、标签栏和状态栏)。然后,您可以将这些边界用于[[UIView alloc] initWithFrame:]loadView 中的 frame 参数。

如果这是您想要的,那么您可能会发现我在这里的回答很有帮助: 确定 loadView 中的正确大小

于 2013-03-20T17:23:05.057 回答