layoutSubviews called twice when rotating
Asked Answered
C

1

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?

Compeer answered 29/1, 2013 at 21:25 Comment(4)
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 orientationDemodulation
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?Compeer
is there a problem with -layoutSubviews being called twice?Ingeingeberg
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 somethingCompeer
K
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)
Kafiristan answered 10/3, 2013 at 17:43 Comment(2)
Hi Armin, welcome to SO. We discourage link-only answers, can you summarize the contents of that link?Ramah
Yes! Thank you for telling me about that :) I posted the summary and marked what I find to be helpful in bold.Kafiristan

© 2022 - 2024 — McMap. All rights reserved.