直接设置控制器视图和添加视图作为子视图之间的区别

时间:2009-03-15 21:08:34

标签: iphone

我刚刚开始学习Objective-C和iphone sdk,我有一个问题,希望有人可以帮助解释一下。

以下内容有何不同:

self.view = someView;

[self.view addSubView: someView];

比如说,在一个简单的应用程序中,我们只有一个控制器和一个容器视图(有一些图像子视图)。 这两个陈述有什么区别?我问的原因是因为我在一些示例代码中修补了一下,我注意到视图正在用图像作为子视图进行初始化,如下所示:

if (self = [super initWithFrame:CGRectZero])
{
//adds some images as subviews here
}

据我所知,initWithFrame:CGRectZero,创建一个大小为[0,0,0,0]的帧(基本上不可见)。

当我用

直接设置视图时
self.view = someView;

我注意到视图实际上显示了图像。但是当我将视图添加为控制器的“默认”视图的子视图时,它却没有。所以基本上我的问题是,幕后会发生什么?为什么第一种方法“调整大小”框架,第二种方法不做同样的事情。

3 个答案:

答案 0 :(得分:9)

您在iPhone屏幕上看到的几乎总是视图层次结构。

当您在Mail中查看收件箱时,您会看到一堆视图。这是一个很重要的观点。[1]在其中,有一个导航栏视图,一个表视图和一个工具栏视图。在导航栏视图中,每侧都有一个按钮视图,中间有一个标签视图。在表视图中,有一堆表格单元格视图,每个单元格都有几个标签视图。工具栏有五个按钮视图。我可以进一步讨论这些按钮内的视图等等,但我相信你明白了。

任何给定视图上方的视图都是其超视图;下面的观点是它的子视图。因此,表格单元格视图将表视图作为其超级视图,并将一组标签视图作为其子视图。顶视图(包含其中所有其他视图的视图)称为根视图。

每个视图都有自己的绘图表面。由该绘图表面形成的矩形称为框架。视图的框架相对于其包含视图的框架。因此,如果我们的一个表格单元格的标签子视图的框架位于(0,0),这意味着它将位于表格单元格的左上角,即使单元格位于屏幕的中间位置。

当您编写视图控制器时,self.view是我之前提到的根视图;所有其他视图都是该视图的子视图(或其子视图的子视图等)。视图控制器的一个功能是它会自动调整其self.view的大小以适应屏幕。 (通话中间的可用区域会更小:状态栏的高度是后者的两倍,因此应用程序的空间更小。如果您的视图控制器由导航控制器或选项卡管理,它也会更小吧控制器,但这是一个不同的故事。)但仅仅因为你调整其根视图的大小并不意味着根视图的子视图将自动调整大小。要做到这一点,你需要设置他们的自动调整掩码(一个告诉视图在超级视图改变大小时应该如何反应的属性):

someView.autoresizingMask = UIViewAutoresizingFlexibleWidth
                          | UIViewAutoresizingFlexibleHeight;

(在Interface Builder中设置自动调整蒙版的图形方式 - 单击检查器窗口中的标尺图标,然后查看“自动调整大小”部分。)

即使这还不够,如果someView的大小不合适。为此,请在将其添加为self.view

的子视图之前调整其框架
someView.frame = CGRectMake(
                            0, // all the way to the left
                            0, // all the way at the top
                            self.view.frame.size.width, // same width as the root view
                            self.view.frame.size.height, // same height too
                           );

那么,为什么你必须使用子视图,如果你必须完成所有这些根本视图为你做的事情?简单:您只能有一个根视图,但是一个视图几乎永远不足以满足您的需要。当然,如果你真的只需要一个视图,你可以将它设置为根视图并继续你的快乐方式,但可能的是,事情比这更复杂。

[1]我在这里简化了一下,但现在这很好。

答案 1 :(得分:1)

将视图添加为子视图时,您需要确保实际添加到现有视图。

self.view = view设置控制器的视图。如果没有这个(在代码中或在XIB中完成),你将永远不会看到任何东西,因为控制器没有显示的视图。

[self.view addSubView: someView]假设已经设置了self.view。如果没有,则您将someview添加为nil的子视图,并且永远不会被看到。

基本上,将self.view视为大容器,所有子视图都只是其中的一部分。如果您不需要任何子视图,将self.view设置为UIImageView或UIWebView就可以了。如果你需要子视图,你需要一个大的空容器视图来放置它们。

在您的情况下,我打赌self.view从未设置,并且您将图片视图添加到nil

答案 2 :(得分:0)

设置视图控制器“view”属性只会更改它正在管理的视图。

将视图添加为另一个视图的子视图,实际上会在另一个视图下添加子视图。

它们是非常不同的东西,因为一个调整视图控制器而另一个调整视图层次结构。

作为猜测,你没有看到任何第一种方式的原因是你添加的子视图的框架是CGRectZero(大小为0)。