3

Using Xcode 4.2/iOS5.0

I have a viewController and an associated viewController.xib. The viewController is set up as the .xib's file's owner. It is invoked from a UINavigationController.

I am attempting some manual layout when the device is rotated portrait/landscape

As I understand it the UIView method to override is

- (void)layoutSubviews;

this is where you do the layout

But - as with drawRect - you do not call this directly, it is invoked when appropriate by iOS

Instead you call setNeedsLayout...

So I have this in the ViewController

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)
         fromInterfaceOrientation {
   [[self view] setNeedsLayout];
 }

and in the same ViewController I have this

- (void)layoutSubviews {
    //.manual override of automatic layout on rotation
NSLog(@"layoutSubviews");
 }

However layoutSubviews does not get called and I don't understand why.

Here is a clue... If I call layoutSubviews directly as [self layoutSubviews]

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)
         fromInterfaceOrientation {
   [self layoutSubviews];
 }

it does trigger

But if I call it as [[self view] layoutSubviews] it does not

So it appears that the view and it's controller are not wired up correctly?

rsswtmr
  • 1,776
  • 5
  • 16
  • 26
user1054941
  • 33
  • 1
  • 3
  • This will help http://stackoverflow.com/questions/5031292/layoutsubviews-only-called-once-despite-any-device-rotation – iPatel May 28 '16 at 13:41

2 Answers2

5

Your problem here is you've implemented -layoutSubviews on your view controller, instead of on your view. It will never be called this way. -layoutSubviews is a mechanism by which a custom view can lay out its own subviews (e.g. a UIButton that has a UIImageView for the image and a UILabel for the label, and uses -layoutSubviews to ensure the imageview and label are all positioned correctly). It's not a mechanism by which a view controller can control the layout of its views.

If you want to change layout on rotation, then you should just go ahead and set up the new layout inside of -didRotateFromInterfaceOrientation:.

JosephH
  • 37,173
  • 19
  • 130
  • 154
Lily Ballard
  • 182,031
  • 33
  • 381
  • 347
  • Thanks. I followed your suggestion, it just works... I am quite new to this, still getting used to the relationship between views, controllers, models, apps. – user1054941 Nov 21 '11 at 22:19
  • Typo: -didRotateFormInterfaceOrientation: should be -didRotateFromInterfaceOrientation: I tried to silently fix with a direct edit, but it was considered too trivial... – user1054941 Nov 21 '11 at 22:27
0

For the general question, this also happens when you forget to call addSubview with your subview on the superview.

user1122069
  • 1,767
  • 1
  • 24
  • 52