What Is a View Hierarchy?
In addition to being responsible for drawing and handling user events, a view instance can act as a container, enclosing other view instances. Those views are linked together creating a view hierarchy. Unlike a class hierarchy, which defines the lineage of a class, the view hierarchy defines the layout of views relative to other views.
The window instance maintains a reference to a single top-level view instance, call the content view. The content view acts as the root of the visible view hierarchy in a window. The view instances enclosed within a view are called subviews. The parent view that encloses a view is referred to as its superview. While a view instance can have multiple subviews, it can have only one superview. In order for a view and its subviews to be visible to the user, the view must be inserted into a window’s view hierarchy.
This window’s view hierarchy has these parts.
- The window is represented by an NSWindow instance.
- The content view serves as the root of the window’s view hierarchy.
- The content view contains a single subview, an instance of a custom class (that looks remarkably like an NSBox, but is not.).
- The custom view instance that, in turn has two subviews, an NSButton instance, and an NSTextField instance.
- The superview for both the button and text field is the NSBox object. The custom view container actually encloses the button and text field views.
Locating Views in the View Hierarchy
A rich selection of methods allows applications to access a view’s hierarchy. The
superview method returns the view that contains the receiver, while the
subviews method returns an array containing the view’s immediate descendants. If a view is the root of a view hierarchy, it returns
nil when asked for its superview. Sending a view the
window message returns the window the view resides in, or
nil if the view is not currently in a window’s view hierarchy.
Other methods allow you to inspect relationships among views:
isDescendantOf: confirms the containment of the receiver;
ancestorSharedWithView: finds the common container containing the receiver and the view instance specified as the parameter. For example, assuming a view hierarchy as shown in Figure 3-2, sending
isDescendentOf: message with
contentView as the parameter returns
ancestorSharedWithView: message, passing
viewC as the parameter, returns
opaqueAncestor method returns the closest parent view that’s guaranteed to draw every pixel in the receiver’s frame (possibly the receiver itself).