How does the global view hierarchy change when using UIKit view manipulations?

advertisements

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:

  1. 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?

  2. 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?

  3. The easiest thing to understand: a UIAlertView creates its own window and makes it key.

  4. 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 to showInView:, it isn't added as a subview of the key window, and it doesn't create its own window. How does it appear, then?

  5. 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 and presentModalViewController:animated, where only the displayed view is in the window hierarchy?


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:

  1. Are the views of view controllers below the top controller of the stack actually removed from the window? Yes. When the view controller is popped off the stack its view disappears. Why waste memory holding a view that the user may never see again?
  2. The new viewController's view is the only subview of the kew window. Is this correct? Yes.
  3. ...a UIAlertView creates its own window and makes it key. Yes.
  4. ...the actionSheet isn't in the view hierarchy at all. ... How does it appear, then? It's added by the application above the window. That's what makes it special. It's also what makes is able to appear above all other views even when those views fail.
  5. Is the view of the selected UIViewController moved to the top Yes. Again, stage illusion. You swap out the one controllers view for another controller's view.