【问题标题】:How does the overall view hierarchy change when using UIKit view manipulations?使用 UIKit 视图操作时,整体视图层次结构如何变化?
【发布时间】:2011-01-29 06:02:57
【问题描述】:

我一直试图弄清楚当使用 pushViewController:animatedpresentModalViewController:animated 和 UITabBarViewController 中的选项卡开关以及 UIAlertView 和 UIActionSheet 等方法时,视图层次结构中会发生什么。

(旁注:我这样做是因为我需要知道我创建的特定 UIView 是否在屏幕上可见,而我不知道它或它的超级视图是如何添加到视图层次结构中的。如果有人知道确定这一点的好方法,我会欢迎知识。)

为了弄清楚,我一直在注销 [[UIApplication sharedApplication] keyWindow] 子视图在不同情况下的层次结构。以下是否正确:

  1. 当一个新的 viewController 被推入 UINavigationController 的堆栈时,旧的 viewController 的视图不再在视图层次结构中。也就是只有top view controller的view是UINavigationController的view的子view(根据日志,其实是UILayoutContainerView等几个私有类)。栈顶控制器下方的视图控制器的视图是否真的从窗口中移除了?

  2. 当一个新的 viewController 通过presentModalViewController:animated 呈现时,会发生非常相似的事情。新 viewController 的视图是 kew 窗口的唯一子视图。这是正确的吗?

  3. 最容易理解的事情:UIAlertView 创建自己的窗口并使其成为关键。

  4. 我遇到的最奇怪的事情:UIActionSheet 通过showInView: 方法显示,actionSheet 根本不在视图层次结构中。它不是作为参数传递给showInView: 的视图的子视图,它没有作为关键窗口的子视图添加,也不会创建自己的窗口。那么它是如何出现的呢?

  5. 我还没有尝试过,所以我想知道当切换 UITabBarController 中的选项卡时 keyWindow 层次结构中会发生什么。选择的 UIViewController 的视图是移到了顶部,还是像 pushViewController:animatedpresentModalViewController:animated 一样工作,只有显示的视图在窗口层次结构中?

【问题讨论】:

    标签: iphone uiview uiviewcontroller uiactionsheet uiwindow


    【解决方案1】:

    我现在为 UITabBarViewController 执行了相同类型的日志记录,因此,考虑第 5 部分:

    它的工作方式似乎与 UINavigationController 相同:只有与当前活动选项卡关联的视图控制器的视图位于 keyWindow 的视图层次结构中。

    【讨论】:

      【解决方案2】:

      我认为您在概念上混淆了视图和视图控制器。导航控制器和标签栏控制器都管理其他视图控制器。两者都不管理视图。

      整个应用程序没有视图层次结构,只有视图控制器的层次结构。仅在加载每个受控视图时才存在视图层次结构。然后你有一个 window-->viewController.view-->viewController.view.subviews 的临时层次结构。当您在堆栈上推送/弹出另一个视图控制器时,您将获得另一个视图层次结构。

      视图层次结构是用户看到的舞台错觉。视图控制器层次结构是程序员用来创建这种错觉的舞台设置/后台。不要混淆两者。

      所以:

      1. 栈顶控制器下面的视图控制器的视图是否真的从窗口中移除了? 是的。当视图控制器从堆栈中弹出时,它的视图就会消失。为什么要浪费内存来保存用户可能再也看不到的视图?
      2. 新的 viewController 的视图是 kew 窗口的唯一子视图。这是正确的吗?是的。
      3. ...UIAlertView 创建自己的窗口并使其成为关键。 是的。
      4. ...actionSheet 根本不在视图层次结构中。 ... 那么它是如何出现的呢? 它是由窗口上方的应用程序添加的。这就是它的特别之处。即使这些视图失败,它也是能够出现在所有其他视图之上的原因。
      5. 是否将选中的 UIViewController 的视图移到顶部 是的。再次,舞台幻觉。您将一个控制器视图换成另一个控制器的视图。

      【讨论】:

      • 我想你有点误解了我的问题。视图层次结构是指视图和子视图的层次结构它们出现在屏幕上时。我关于导航控制器的问题是如何将其堆栈上的视图控制器的视图添加到该屏幕层次结构中。我不是在谈论弹出的视图控制器。我说的是另一个视图控制器被推送到的视图控制器。它仍在导航控制器的堆栈中,只是不在顶部。我想确认我做对了:只有顶视图控制器的视图实际上在窗口中
      • (上一条评论中空间不足)感谢操作表上的信息。通过交换,您的意思是只有可见视图在窗口中?
      • (1) 是的,一个视图换成了另一个视图。任何时候只有一个 viewController.view 处于活动状态。 (2) 警报和 UISheets 在技术上是窗口的兄弟视图,即它们存在于层次结构的同一顶层。因此 IIRC,您不会在窗口子视图的任何转储中看到它们(至少是警报)。
      • 谢谢,但是我看到的日志显示 UIAlertView 是它自己的窗口(类 _UIAlertOverlayWindow)的子视图,它是 alertView 在屏幕上时的关键窗口,而 UIActionSheet 不在任何window at all -- 显示时的关键窗口仍然是主应用程序窗口,而actionSheet 不是它的子视图。
      • TechZen 在这里几乎完全倒退了。整个应用程序确实存在一个视图层次结构,从一个(或有时多个)UIWindow 开始,然后下降到其嵌套的子视图。其中一些子视图可以具有与之关联的视图控制器,这些视图控制器可以参与响应者链,但这并不是绝对必要的。您可以编写一个有视图但没有视图控制器的应用程序。导航和标签栏控制器确实管理视图。他们通过操作视图层次结构、为他们管理的控制器添加和删除视图来响应用户操作。
      【解决方案3】:

      UIView 上的以下方法可以满足您的需要:

      – didAddSubview:
      – didMoveToSuperview
      – didMoveToWindow
      – willMoveToSuperview:
      – willMoveToWindow:
      – willRemoveSubview:
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-22
        相关资源
        最近更新 更多