2009-07-09 72 views
28

摘要:UIViewController在初始化该视图时应该如何知道其UIView实例的大小?何处确定UIView大小

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

当创建视图 层次的意见,你应该总是设置您的看法 自动尺寸属性。 当显示 屏幕上的视图控制器,其根视图通常是 调整大小以适合可用的空间, 可以变化取决于 窗口的当前取向和 存在其他界面元素 如状态栏的。

因此,UIViewController实例应该设置这些属性。迄今为止,迄今为止,UIViewController并不需要知道其观点是多大还是将会如此。

当请求UIViewController的视图并且视图属性为零时,将调用视图控制器的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 = ...)

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

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

回答

8

你不要必须使用指定的初始值设定项。只需使用[[UIView alloc] init]中的init即可。指定的初始化器必须从子类的初始化器中使用。

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

+10

的UIView的init方法实际上具有零矩形 – drvdijk 2009-07-09 12:43:16

+0

现在我注意到调用initWithFrame,同时施加变换到一个视图中, layoutSubviews被调用。考虑到我在视图控制器的touchesMoved方法中应用了转换,在layoutSubviews中做了很多工作也不会被推荐... – drvdijk 2009-07-15 12:28:19

0

我目前正试图从UIViewController的子类来创建一个通用组件后,完成同样的事情,来到注意到相当奇怪的事情:

的UIViewController有一个“的loadView”方法,你可能会覆盖到(引用文档)“这是子类应该创建自定义视图层次的地方”。所以,我创建我的视图层次结构,使用默认帧大小合成我的屏幕(因为我可能不知道我应该在调用loadView时显示的框架)。

但是,然后,根据什么呼叫我正确设置帧大小?又名:我的视图控制器在什么时候知道它的视图实际大小?

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

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

编辑:刚刚发现的UIViewController文档此注: 注意:你不应该使用视图控制器来管理意见只能填充其窗口,也就是说,只能由应用程序内容矩形定义的区域的一部分的一部分。如果您希望有一个由多个较小视图组成的界面,请将它们全部嵌入到单个根视图中,并使用视图控制器来管理该视图。

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

这对我来说确实存在一个问题,因为我试图创建一个自定义的UITabBarViewController(为了能够在tabbar中显示自定义图像,而不是蓝色渐变):我的tabBarViewController应该显示子视图控制器到只有窗口...

0

您可能想要计算可用屏幕空间(取决于导航栏,选项卡栏和状态栏等其他视图的存在)的边界。您可以将这些界限用于loadView中的[[UIView alloc] initWithFrame:]中的框架参数。

如果这是你想要的,那么你可能会发现我的答案在这里有用的东西: Determine the correct size in loadView