当我们执行presentViewController时会发生什么?

时间:2013-04-24 13:21:10

标签: iphone ios objective-c ipad uiviewcontroller

鉴于以下代码

self.view.backgroundColor = [UIColor yellowColor];
MyViewController *myVC = [[MyViewController alloc] initWithNibName:@"MyView" bundle:nil]
myVC.view.backgroundColor = [UIColor clearColor];
myVC.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:myVC animated:NO completion:nil];

当我们调用presentViewController时会发生什么?当myVC可见时,我看不到黄色,然后我在它的viewDidAppear方法中检查了myVC.view.superView,它是UIWindow。

Q1。这意味着直到模态窗口向上呈现ViewController.view(上面的情况中的self.view)从View层次结构和presentViewController.view中移除(上面的myVC.view)在UIWindow上添加?

Q2。如果myVC.modalPresentationStyle!= UIModalPresentationFullScreen将会是什么情况?

Q3。除了presentViewController.view之外,iOS还会删除UIWindow中的所有视图,直到全屏模式对话框进行优化吗?如果不是为什么不呢?

1 个答案:

答案 0 :(得分:18)

首先,让我们讨论一下没有动画的情况。

在致电present之前:

  1. 您的窗口有一个视图层次结构,从rootViewController视图开始。
  2. 致电present:

    1. 视图层次结构仍然存在且没有更改。
    2. 一个名为“调光视图”的特殊全屏视图被添加到窗口中(即,不在rootViewController视图内但在窗口内(窗口也是UIView)这个视图是透明的,使呈现的控制器变暗并阻止用户交互。
    3. 然后将呈现的(模态)控制器视图添加到窗口中。
    4. 在窗口和显示的控制器窗口之间添加了一些其他视图。如果您记录视图层次结构,您将看到名为_ControllerWrapperView的类或类似的类。但是,这在iOS版本之间已经发生了变化,您不应该依赖于视图结构。 请注意,模态控制器不能透明,因为它不是窗口的直接子视图,控制器和窗口之间的包装器不透明。

      动画案例几乎相同。只有步骤之间有一些奇特的动画。

      编辑2: 答案真的有点不对劲。 iPhone和iPad提供的控制器之间存在很大差异。

      在iPhone上,显示的控制器始终全屏显示,实际控制器实际上已从窗口中删除。

      在iPad上,如果呈现的控制器不是全屏(请参阅UIModalPresentationStyle),则呈现控制器会保留在窗口中。

      您的问题:

        

      这是否意味着直到模态窗口向上呈现ViewController.view(上面的情况中的self.view)从View层次结构中移除并且在UIWindow上添加了presentViewController.view(上面的例子中的myVC.view)?

      如果控制器是全屏的,那么这种说法是正确的。否则,呈现视图控制器保持在那里但整个内容与其他视图重叠(即使它们是半透明的)。此外,在呈现的控制器视图和呈现的控制器视图之间总是存在一些视图。

        

      如果myVC.modalPresentationStyle!= UIModalPresentationFullScreen会是什么情况?

      请参阅上一个问题的答案 - 在iPhone上,没有区别。

        

      除了presentViewController.view之外,iOS还会从UIWindow中删除所有视图,直到全屏模式对话框进行优化吗?如果不是为什么不呢?

      从我的测试中,只有呈现控制器从窗口层次结构中删除。这可能是为了优化绘图性能。这是系统可以安全删除的唯一控制器。删除任何其他视图可能会导致问题(例如,应始终可见的视图)。

      修改: 如果你想制作一个透明的控制器,你可以:

      1. 使用过渡动画(+[UIView transition...]
      2. 将视图直接添加到视图层次结构(控制器视图或窗口)
      3. 同样但也将子控制器添加到控制器中。