UIScrollView has a Secret

Dave Smith
Dave Smith

Sometimes, it's not always clear in iPhone development when one should create their interface elements using Apple's Interface Builder (IB) application, or directly in application code. Oftentimes, with more complex view issues, the answer tends to be a combination of both. When doing this, however, it is not uncommon for little traps to come out of hiding that can be hard to trace down.

IB Attributes

One such instance lives within the UIScrollView element. The developer may choose to lay out the element in its superview using IB to ensure proper placement and sizing relative to the rest of the view. However, because of the dynamic nature of content placed within UIScrollView, the population and sizing of the content view may take place in code. When using IB to lay out a UIScrollView, the Attributes Inspector will give the developer options similar to what is shown on the right.

The Scrollers Are Hiding

I want to draw your attention to the checkboxes named "Horizontal" and "Vertical" by Scrollers heading. As many of you may know, these options turn the scroll bars that appear on the sides of the view during a scroll operation ON and OFF. By default, these boxes are checked and the scroll bars are active.

Now for the secret: When those scrollers are active, the unarchived version of your object will have two extra UIView objects in your subviews array... one for each scroller bar. If you were to look at the object in the Xcode debugger, you would see that the type of these objects is actually _UIStretchableImage (which is a private UIView subclass).

This means that, if you plan to iterate over the subviews array at any time, your code may throw an exception on unrecognized selector or some other method because it is accessing objects in that array you may not have known existed (and don't understand your custom message).

Secret #2: _UIStretchableImage is also a subclass of UIImageView, or at least to the point that it will return YES from a call to [view isKindOfClass:[UIImageView class]]. Therefore, if you like to use UIScrollView for images and think you can outsmart this by checking the type of each subview object, you'll have to use another method.

This can also have consequence if you plan to loop through the subviews array to clear the content with [view removeFromSuperview], so be aware of that as well. You may just lose your scroll bars without realizing why!