6

When my main view rotates I want to re-arrange the sub views, so in my ViewController, I override

willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration

and set the frames of the subViews in there. This is all well and good, but in the subViews I have also overridden

 layoutSubviews

so they layout themselves correctly. But the problem is this now gets called twice - presumably once when I set the Frame in willAnimateRotationToInterfaceOrientation and once because of the rotation. (If I don't set the Frame it gets called once.)

Surely it's the responsibility of the ViewController to layout the frames so this seems like a design flaw - what's the solution so layoutSubviews is only called once?

istepaniuk
  • 4,016
  • 2
  • 32
  • 60
Bbx
  • 3,184
  • 3
  • 22
  • 33
  • You can save the last orientation in a private variable and execute the layoutSubviews code only if lastOrientation != currentOrientation and just after executing layoutSubviews code , set lastOrientation = currentOrientation, this way it will only get called once in a single orientation – Dhruv Goel Jan 29 '13 at 21:36
  • Yea, I did think of that but seems a bit cludgy. And what if I do want to change the frame at some other time than in rotate - then layoutSubviews would not do anything! There MUST be a better way - how is this supposed to be done cleanly? – Bbx Jan 29 '13 at 21:39
  • 1
    is there a problem with `-layoutSubviews` being called twice? – Simon Goldeen Jan 29 '13 at 21:42
  • Well, it's not the end of the world, but it's inefficient and I'd be surprised if that was the intended design, so makes me think I'm missing something – Bbx Jan 29 '13 at 22:30

1 Answers1

19

I had the same question. I found this page to be helpful for me. Is this useful for you?

EDIT: Here is the summary of the page (copied):

  • init does not cause layoutSubviews to be called (duh)
  • addSubview causes layoutSubviews to be called on the view being added, the view it’s being added to (target view), and all the subviews of the target view
  • setFrame intelligently calls layoutSubviews on the view having it’s frame set only if the size parameter of the frame is different
  • scrolling a UIScrollView causes layoutSubviews to be called on the scrollView, and it’s superview
  • rotating a device only calls layoutSubview on the parent view (the responding viewControllers primary view)
  • removeFromSuperview – layoutSubviews is called on superview only (not show in table)
Armin
  • 1,807
  • 20
  • 21
  • 1
    Hi Armin, welcome to SO. We discourage link-only answers, can you summarize the contents of that link? – buildsucceeded Mar 10 '13 at 18:02
  • 1
    Yes! Thank you for telling me about that :) I posted the summary and marked what I find to be helpful in bold. – Armin Mar 10 '13 at 18:24