8

First time posting on stack overflow.

I've spent hours scouring over many Google searches and have, at this point, practically memorized the UIView and UIViewController class reference docs. No matter what I do, my app is ignoring my efforts to resize my views on orientation change (or any other frame size modifications for that matter.)

There are no nibs or xibs involved; I am building all of my views and viewcontrollers programmatically, and they (the viewcontrollers) are all subclasses of one of three custom UIViewController subclasses that I have created. These super classes have the following lines in their loadView: method...

[self setView:[[[UIView alloc] initWithFrame:[self viewFrame]] autorelease]];
[[self view] setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
[[self view] setAutoresizesSubviews:TRUE];

In all of the appropriate setter methods (wherever I add a subView in other words) I am repeating the steps of applying the autoresizingMask. It seems that no matter what I do, the outcome is always the same -- I click build, click debug, wait for the app to launch, rotate the device, and presto! The view rotates but does not resize at all.

What am I missing here? It's probably something obvious that I am just not seeing. Any help is truly appreciated, thanks in advance.

quickthyme
  • 1,250
  • 1
  • 13
  • 16

1 Answers1

34

Well, sure enough, it was my own fault.

Lesson number one: You are not doing yourself any favors by staying up all night trying to fix broken code. Get some rest! Drink more water! You will only probably make things worse if you keep trying to force your brain to perform complicated algorithmic strategy and logic past its bed-time.

Turns out I had a rogue UIView toward the bottom of the view hierarchy that did not have the autoresize property set at all. I thought I had looked through everything, but turns out that I missed one. (Just one little view, and an entire day shot!)

I can say for anyone who comes along later with similar frustration, that Autoresizing does indeed work as documented. If you think that "something is not being called" then you are probably looking in the wrong place. Also, the UIViewAutoresizingMask enum constants are not used exactly like they are in Interface Builder. In IB, you "lock" margins, whereas in setting them programmatically, the locked margins are assumed by default and you "unlock" them by setting it as "Flexible". So for example, setting only the FlexibleWidth and FlexibleHeight bits is equivalent to enabling all autoresizing options in IB. By throwing in any of the margin masks (i.e. UIViewAutoresizingFlexibleLeftMargin) you are "deselecting" the corresponding margin autoresizing option in IB. (I've seen many other posts floating around where this seemed to be a major point of confusion for some folks.)

During my research, however, I did notice that there does not seem to be any sort of event, message, notification, or otherwise when a UIView gets resized, whether automatically or not. While not necessary for resizing subViews, it would be nice to know when it's happening in the situation where you would like to cause a scrollView or tableView to scroll should it's frame size ever change. I know one can easily do this when the keyboard pops up, because there is a notification system around that as well as the TextField delegate methods. So maybe a topic for another post...

Anyway, thank you everyone who participates on StackOverflow!

Ravi Gautam
  • 960
  • 2
  • 9
  • 20
quickthyme
  • 1,250
  • 1
  • 13
  • 16
  • 2
    Overriding -setFrame: is a pretty reliable way to see that a view has resized. – aksommerville Jul 05 '11 at 12:50
  • Oh yeah, sure! I use that technique all the time when debugging retain counts, but I often overlook doing that in other situations such as this. (Funny how evasive the obvious can be.) To clarify your comment for others, this is referring to overriding -setFrame in order to spit up some NSLog that tells you the name of the view and some frame values. (Don't forget to call super's implementation if you try this.) – quickthyme Jul 25 '11 at 05:47
  • Other than that, I wouldn't use that method for anything else. I would also make dure to disable the override before releasing the code as production. – quickthyme Jul 25 '11 at 21:47
  • where do you override setFrame? The UIViewController or UIView subclass? – user4951 Oct 16 '12 at 06:29
  • 'setFrame:' is on UIView. Also, if you need to know when it happens to any and all views, you can create a category method that affects all UIView and subclasses and logs the event. Again, I advise against using this method for any other purpose than temporary troubleshooting. Any updates to the content of a view should be handled by its view controller. – quickthyme Nov 02 '12 at 16:07
  • 1 up for "Lesson Number one" :) – Surender Rathore Mar 31 '13 at 08:20