Wednesday, December 8, 2010

UIView Category to manage the z-order of views


This is revamp of the article from February, but in an email John Muchow he pointed out a demo project will help a lot to make clear what the category does, so I included a demo project which can be downloaded from here.
Any UIView can have a hierarchy of subviews. The subviews hierarchy defines which UIView child appears on top of others. The mechanism works in the pretty much same way as the z-index property in CSS or the depth of the MovieClips in Flash/Flex.
However the Apple developer docs are a bit vague on the details, and one should figure out himself how exactly to use the UIView instance methods provided for managing the subviews hierarchy.

What the developer docs don’t say

As Bandon Bodnar figured out on Stackoverflow what’s missing from the docs is:
  • the order of the subviews array in UIView defines the depth of the children subviews
  • the more in the beginning of the subviews array the view is, the deeper it appears in the hierarchy (i.e. subview at position 0 appears at the back, or under all other subviews)
  • respectively the higher is in the index of the view in the subviews array, the more to the front it is, the last object in the array appears on top of all other subviews
Now the fact Apple doesn’t go in details about those, could mean they might want to change this behavior in the future, but if one intends to write a layout heavy app he needs to use the layout hierarchy functionality no matter.

UIView Hierarchy Category

In a game setup, or just in a GUI heavy app it is really great to have more control over the elements hierarchy. Especially in a game though, views could represent different object, which would need to go behind each other, react to interaction and must be checked regularly whether they are over other objects or not. In these cases, the Hierarchy Category empowers UIView with handy methods to manage the depth where the view appears.

@interface UIView (Hierarchy)
 
-(int)getSubviewIndex;
 
-(void)bringToFront;
-(void)sendToBack;
 
-(void)bringOneLevelUp;
-(void)sendOneLevelDown;
 
-(BOOL)isInFront;
-(BOOL)isAtBack;
 
-(void)swapDepthsWithView:(UIView*)swapView;
 
@end
Most of the methods are one-liners, but they really bring the game on the UIView’s side.
-(int)getSubviewIndex;
Returns the index of the view in the subviews array of its superview. Basically no alternative to it in the UIView methods. Apple might change the behavior the method uses to determine the subview index, but that’s why there’s abstraction and app updates.
-(void)bringToFront;
-(void)sendToBack;
Wrappers around the parent UIView respective methods, they just save you some code writing and extracting from the subviews array.
-(void)bringOneLevelUp;
-(void)sendOneLevelDown;
Very handy if you are rearranging the UI programatically. I spent good half an hour to come up with names for those two, but in the end these names made most sense out of all the candidates. There’s no restriction how many times can those two be called, if the view is on top already it will just stay on top if further calls to bringOneLevelUp are made.
-(BOOL)isInFront;
-(BOOL)isAtBack;
As the names suggest those tell whether a view is on top or the bottom of the subview hierarchy.
-(void)swapDepthsWithView:(UIView*)swapView;
Another wrapper around the existing UIView methods. However I believe it makes more sense to say “You, view1 exchange your place with this other view2″.
UIView hierarchy wrap up and a download link
Of course the code is available for download. Use it as you find proper, just include the .h file and all UIViews will have the described above methods.
#import "UIView+Hierarchy.h"
I take no responsability for any demages cause by this code. You are free to use it for free or commercial applications.
Download demo project including the UIView+Hierarchy category

No comments:

Post a Comment

Followers