views:

430

answers:

2

I'm using a subclass of a UIView to (programmatically) contain and manage numerous subviews (mostly UIImageViews) that are to be positioned adjacent to each other such that none are overlapping. It's safe to assume that the subviews are all the same height (when originally drawn), but are varying widths. The container might be resized, in which case I want the subviews to be scaled proportionally. Moreover, there are times when I need to add/remove/edit any given subview (which might change its width).

I'm had some success in using:

[self setAutoresizesSubviews:YES];
[self setAutoresizingMask:(UIViewAutoresizingFlexibleLeftMargin  |
                               UIViewAutoresizingFlexibleWidth       |
                               UIViewAutoresizingFlexibleRightMargin |
                               UIViewAutoresizingFlexibleTopMargin   |
                               UIViewAutoresizingFlexibleHeight      |
                               UIViewAutoresizingFlexibleBottomMargin)];

to have the container automatically resize its subviews when its frame changes.

Unfortunately, I'm having a lot of trouble dealing with the case when the contents of a subview changes, causing it to widen or contract. Simply setting 'setNeedsLayout' and defining 'layoutSubviews' for the subview doesn't seem to do the trick because, at the beginning of 'layoutSubviews' the subview's frame hasn't been adjusted. If I force it, then the current contents are stretched or contracted, which looks terrible.

I'd certainly appreciate it if someone could explain how sizeToFit, layoutSubviews, sizeThatFits:, setAutoresizesSubviews:, setAutoresizingMask:, and setContentMode: should be used in a case like this. I mean, if I want to adjust the contents of a subview (and widen it), then how do I do it such that:

  • the subview is widened (without adversely stretching or autoresizing anything else within it)
  • the container is widened a proportional amount
  • none of the other subviews are affected

?

Thanks in advance!

A: 

For animating the resizing of a view do:

[UIView beginAnimations:@"resizeAnimation" context:nil];
youView.frame = newFrame;
[UIView commitAnimations];

If you don't want an element to resize automatically, just set its autoresize to UIViewAutoresizingNone.

If I get your case correctly, you don't want the containter and its subviews to resize automatically, except the subview you mention. That view should have some autoresizing options enabled (I don't know exactly the ones you want, just try some and see their effect). That subview should also have its subviews resizing disabled.

Marco Mustapic
A: 

I ended up going the manual route, using sizeThatFits: and layoutSubviews to explicitly control how everything was redrawn and organized. I found that setAutoresizesSubviews: and setAutoresizingMask: helped for simple layouts, but that it was hard to debug if I tried anything even slightly atypical.

My advice: the first time you're experimenting with programmatic layouts define sizeThatFits for all of your (sub) views and define layoutSubviews for each. Use debugging statements to log the placement of everything. Once you're happy, consider incorporating autoresizing to simply your code (if possible).

D Carney