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.
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!