总结:初始化该视图时,UIViewController
应该如何知道其UIView实例的大小?
UIView的专用初始化方法是initWithFrame:(CGRect)frame
方法。这将为新创建的UIView设置框架。如果请求了视图控制器的视图,则可以从UIViewController's
loadView方法调用此方法。关于子类化和视图大小的UIViewController
状态的文档:
为视图创建视图时 层次结构,你应该总是设置 自动调整视图的属性。 显示视图控制器时 屏幕,其根视图通常是 调整大小以适应可用空间, 这可能会有所不同 窗口的当前方向和 存在其他界面元素 例如状态栏。
因此,UIViewController
实例应该设置这些属性。到目前为止,UIViewController
到目前为止还没有必要知道它的观点有多大。
当请求UIViewController
的视图且视图属性为nil时,将调用视图控制器的loadView方法。现在有一个问题,因为UIView
需要初始化,但视图控制器仍然不知道视图应该是多大。你应该初始化那个视图有多大?您在代码中确定视图大小的位置?
您可以使用零rect(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的新初始化方法(从而赋予它一个帧属性)?或者我错过了什么,还有其他可能吗?
答案 0 :(得分:8)
您不必使用指定的初始值设定项。只需在[[UIView alloc] init]
中使用init即可。必须从子类的初始值设定项中使用指定的初始值设定项。
另一方面,设置两次框架不会造成太大伤害。在setFrame:
执行大量任务是不寻常的。 Layouting通常在layoutSubviews
完成,只执行一次。
答案 1 :(得分:0)
我正在尝试从UIViewController继承子类创建一个通用组件之后完成同样的事情并且注意到一些非常奇怪的东西:
UIViewController有一个“loadView”方法,你可以覆盖它(引用文档)“这是子类应该创建自定义视图层次结构的地方”。
所以,我创建了我的视图层次结构,使用默认的帧大小合成我的屏幕(因为我可能不知道框架,我应该在调用loadView时显示内容)。
但是,在什么电话中我能正确设置帧大小? Aka:我的视图控制器什么时候知道它的视图真实大小?
我是否必须在我的ViewController子类中创建一个“setFrame”,创建viewcontroller的对象应该调用它?这看起来很奇怪。
drvdijk:你有解决问题的方法吗?
编辑:刚刚在UIViewController文档中找到了这个注释: 注意:您不应该使用视图控制器来管理仅填充其窗口一部分的视图 - 即,只是应用程序内容矩形定义的区域的一部分。如果您想要一个由几个较小视图组成的界面,请将它们全部嵌入到一个根视图中,并使用您的视图控制器管理该视图。
所以,看来UIViewController主视图总是全屏显示。周期。
这确实给我带来了一个问题,因为我正在尝试创建一个自定义的UITabBarViewController(能够在tabbar中显示自定义图像,而不是蓝色渐变):我的tabBarViewController应该将subviewcontrollers显示为一部分只有窗口...
答案 2 :(得分:0)
您可能想要计算可用屏幕空间的范围(取决于其他视图的存在,如导航栏,标签栏和状态栏)。然后,您可以将这些边界用于loadView中的[[UIView alloc] initWithFrame:]
中的frame参数。
如果这是您想要的,那么您可能会发现我的答案有用: Determine the correct size in loadView