使用 UIKit 视图操作时,整体视图层次结构如何变化?
我一直试图弄清楚当使用诸如 pushViewController:animated
、presentModalViewController:animated
和 UITabBarViewController 中的选项卡开关等方法时,视图层次结构中会发生什么,以及UIAlertView 和 UIActionSheet。
(旁注:我这样做是因为我需要知道我创建的特定 UIView 在屏幕上是否可见,而我不知道它或其超级视图如何添加到视图层次结构中。如果有人知道确定这一点的好方法,我欢迎了解。)
为了弄清楚这一点,我一直在不同情况下注销 [[UIApplication sharedApplication] keyWindow] 子视图的层次结构。以下正确的是:
当新的 viewController 被推入 UINavigationController 的堆栈时,旧的 viewController 的视图不再位于视图层次结构中。也就是说,只有顶视图控制器的视图是UINavigationController的视图的子视图(根据日志,它实际上是UILayoutContainerView等几个私有类)。堆栈顶部控制器下方的视图控制器的视图实际上是否从窗口中删除?
当通过
presentModalViewController:animated
呈现新的 viewController 时,会发生非常类似的情况。新的 viewController 的视图是kew 窗口的唯一子视图。这是正确的吗?最容易理解的事情:UIAlertView 创建自己的窗口并使其成为关键。
我遇到的最奇怪的事情:UIActionSheet是通过
showInView:
方法显示的,actionSheet根本不在视图层次结构中。它不是作为参数传递给showInView:
的视图的子视图,它不会添加为关键窗口的子视图,并且不会创建自己的窗口。那么它是如何出现的呢?我还没有尝试过这个,所以我想知道当 UITabBarController 中的选项卡切换时 keyWindow 层次结构中会发生什么。所选 UIViewController 的视图是否移至顶部,或者是否像
pushViewController:animated
和presentModalViewController:animated
一样工作,其中只有显示的视图位于窗口层次结构中?
I've been trying to figure out what happens in the view hierarchy when methods like pushViewController:animated
, presentModalViewController:animated
, and tab switches in UITabBarViewController are used, as well as UIAlertView and UIActionSheet.
(Side note: I'm doing this because I need to know whether a specific UIView of my creation is visible on screen when I do not know anything about how it or its superview may have been added to the view hierarchy. If someone knows a good way to determine this, I'd welcome the knowledge.)
To figure it out, I've been logging out the hierarchy of [[UIApplication sharedApplication] keyWindow] subviews in different circumstances. Is the following correct:
When a new viewController is pushed onto the stack of a UINavigationController, the old viewController's view is no longer in the view hierarchy. That is, only the top view controller's view is a subview of UINavigationController's view (according to logs, it's actually several private classes such as UILayoutContainerView). Are the views of view controllers below the top controller of the stack actually removed from the window?
A very similar thing happens when a new viewController is presented via
presentModalViewController:animated
. The new viewController's view is the only subview of the kew window. Is this correct?The easiest thing to understand: a UIAlertView creates its own window and makes it key.
The strangest thing I encountered: a UIActionSheet is shown via
showInView:
method, the actionSheet isn't in the view hierarchy at all. It's not a subview of the view passed as an argument toshowInView:
, it isn't added as a subview of the key window, and it doesn't create its own window. How does it appear, then?I haven't tried this yet, so I'd like to know what happens in the keyWindow hierarchy when tabs in a UITabBarController are switched. Is the view of the selected UIViewController moved to the top, or does it work like with
pushViewController:animated
andpresentModalViewController:animated
, where only the displayed view is in the window hierarchy?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为您在概念上混淆了视图和视图控制器。导航控制器和标签栏控制器都管理其他视图控制器。两者都不管理视图。
整个应用程序没有视图层次结构,只有视图控制器的层次结构。仅当加载每个受控视图时,视图层次结构才存在。然后你就有了一个 window-->viewController.view-->viewController.view.subviews 的临时层次结构。当您在堆栈上推送/弹出另一个视图控制器时,您将获得另一个视图层次结构。
视图层次结构是用户看到的舞台幻觉。视图控制器层次结构是程序员用来创建这种幻觉的舞台布景/后台。不要混淆两者。
那么:
I think you're conceptually confusing views and views controllers. Both the navigation controller and the tabbar controller manager other view controllers. Neither manages views.
There is no view hierarchy for an entire app, there is only a hierarchy of view controllers. A view hierarchy only exist when each controlled view is loaded. Then you have a temporary hierarchy of window-->viewController.view-->viewController.view.subviews. When you push/pop another view controller on the stack, you get another view hierarchy.
The view hierarchy is an stage illusion that the user sees. The view controller hierarchy is the stage-set/backstage that the programer uses to create that illusion. Don't confuse the two.
So:
我现在对 UITabBarViewController 执行了相同类型的日志记录,因此,考虑第 5 部分:
它的工作方式似乎与 UINavigationController 相同:只有与当前活动选项卡关联的视图控制器的视图位于 keyWindow 的视图层次结构中。
I now performed the same sort of logging for UITabBarViewController, so, considering part 5:
It seems to work the same way as UINavigationController: only the view of the view controller associated with the currently active tab is in the view hierarchy of keyWindow.
UIView 上的以下方法可能会满足您的需要:
the following methods on UIView may do what you need: