不建立视图的情况下,是否有可能在程序中以编程方式创建UIViewController?

3
我想以编程方式创建一个UIViewController,而不使用nibs或storyboards。它将被创建并呈现,并且在自己的类中设置要显示的图像。
但是,每当我只是alloc init一个视图控制器并展示它时,它呈现为黑色。
我认为这是因为它缺少自己的视图?
当我在Storyboard中创建一个原始的UIViewController时,它会自动设置一个视图,如何设置视图,使其与Storyboard一样具有适当的设备大小、旋转变化等属性?
3个回答

5
希望我的回答能够澄清一些事情,尽管已经有一个被接受的答案。我认为那里给出的解释不够清晰,这可能是为什么原始问题的提问者一开始没有按照它所说的去做,导致提问者更加困惑,回答者在评论中表现得很刻薄,这并没有帮助任何人。这不是这个网站的初衷。
当我只是分配并初始化 [UIViewController] 并呈现它时,它会以黑色显示出来。
实际上它不是黑色的。它是透明的(或者更准确地说,它的 view 是透明的),所以你真正看到的是从视图后面传来的黑色(在这种简单情况下,很可能是 UIWindow 本身)。
这是因为您依赖于您的 UIViewController 中的默认的 loadView 实现,该实现仅创建了一个 UIView 实例,并且 UIView 的背景属性默认为 nil,因此它是透明的。 但是,在界面构建器中设置它时,它通常会为您设置 backgroundColor 属性为白色。
当然,您也可以在代码中自己实现这一点。 下面是一个示例,显示了完全相同的内容,只不过我使用的是绿色,因此当您呈现它时,您肯定会看到这个特定的视图:
UIViewController* plainViewController = [UIViewController new];
plainViewController.view.backgroundColor = [UIColor greenColor];

当然,使用UIViewController而不进行子类化并没有太多意义,但你可以这样做。你只需像我上面做的那样在外部管理所有内容。
如果你进行子类化UIViewController,你只需要实现自己的loadView方法来创建自己的UIView(或其子类),但请记住,在这里它也将是透明的,除非你显式设置其backgroundColor。以下是几种实现方式...
在自己的UIViewController.m子类中,用默认的UIView实例初始化背景...
- (void) loadView
{
    [super loadView]; // Actually loads and assigns the default view

    // Set the background on the default view
    self.view.backgroundColor = [UIColor greenColor];
}

或者使用自定义的UIView子类...

- (void) loadView
{
    // Create and initialize your custom view
    MyCustomUIView* myCustomUIView = [MyCustomUIView new];
    myCustomUIView.backgroundColor = [UIColor greenColor];

    // You're setting the view so do *not* call [super loadView]
    self.view = myCustomUIView;
}

您也可以在viewDidLoad中初始化背景,像这样(这适用于上述任何版本)。

- (void) viewDidLoad
{
    // Set the background on whatever view is being managed
    // regardless of where/how it was created
    self.view.backgroundColor = [UIColor greenColor];
}

注意:当使用viewDidLoad时:
  1. 在上述第一种情况下,您可以完全删除loadView,因为它不再需要,super现在会处理创建视图。
  2. 在第二种情况下,保留loadView但删除设置backgroundColor属性的那行代码,因为您现在是在viewDidLoad中进行设置。

然而,所有这三种方法的好处是现在视图的初始化都包含在您的UIViewController中,使得重用更加容易。

顺便提一下,UIWindow本身是UIView的子类,因此它也有一个backgroundColor属性(默认情况下也是nil)。因此,如果您将窗口的backgroundColor属性更改为紫色,那么您看到的就是紫色而不是黑色(直到您在视图上设置背景颜色,这将完全覆盖窗口)。

我认为这是因为它缺少自己的视图?

希望上述原因澄清了这个错误的假设。它实际上存在,只是透明的。

仅仅访问UIViewControllerview属性将创建视图,如果它不存在。由于呈现新实例化的UIViewController需要访问其view属性才能有东西进行呈现,因此在那时创建了视图。但是,在上述情况下,我明确访问view属性以便在其上设置backgroundColor属性,是创建视图的时间点。

无论如何,希望这更清楚地解释了您看到的内容以及幕后发生的事情。一旦掌握了以编程方式创建和使用ViewControllers,就会变得非常简单。即使如此,使用故事板或甚至使用Interface Builder的NIB仍然更容易,因为您可以直观地看到自己所做的事情。


3
然而,每当我只是分配初始化一个视图控制器并呈现它时,它就会以黑色出现,因为它是原始的UIViewController。您无法修改/自定义它;它不是您的类。相反,创建一个UIViewController子类,例如MyCoolViewController,并实例化和呈现它。区别在于,使用MyCoolViewController,您可以覆盖viewDidLoad和其他方法,从而将一些有用的界面放入其视图中。
如何设置视图以使其像Storyboard一样具有正确的设备大小,旋转时更改等?
不要担心;所有这些都会自动发生,因为视图由视图控制器管理,并且视图控制器被正确地放置在视图控制器层次结构中(例如通过说“presentViewController:...”)。

我的书教你如何自定义视图控制器子类的视图,并提供一些代码供你使用;从这里开始:http://www.apeth.com/iOSBook/ch19.html#_manual_view - matt
我很快就会上传一个示例项目。我似乎正在做这件事。 - Doug Smith
这是一个示例项目:http://cl.ly/0B3S1E0n1v3j 我创建了子类,然后呈现它,但它是黑色的。 - Doug Smith
我理解了你的问题 - 你的示例项目并没有增加我不知道的内容。你有尝试阅读我的答案和上面的评论吗? - matt
1
这是关于我的视图控制器显示的问题吗?它变成黑色让我觉得有问题,因为当你添加一个没有自定义的视图控制器时,视图应该是白色的。我离开了电脑,没有想到他们只是选择了不同的颜色。天啊。 - Doug Smith
显示剩余9条评论

1

来自文档

如果您无法在Storyboard或Nib文件中定义视图,请重写loadView方法以手动实例化视图层次结构并将其分配给view属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接