I have a view with subviews that I manage by overriding
layoutSubviews. This of course gets called to do the initial layout when the view is created. I call
setNeedsLayout as needed to make changes to the layout due to state changes in the app. This all works.
To handle rotation, I'm overriding
viewWillTransitionToSize:withTransitionCoordinator: to do a little work to prepare for rotation (nothing visible; just internal state), then just allowing
layoutSubviews to be called as expected with the new size. That is working great.
As a result of a discussion here on a related topic, I'm working on moving the layout and animation of my subviews into a call to
animateAlongsideTransition:completion: which coordinates the animation of my subview frame changes with the rotation animation. So in
viewWillTransitionToSize:withTransitionCoordinator: I'm figuring out all my new frames, then doing the call to
animateAlongsideTransition:completion: to animate the frame changes.
The problem is that before my animation appears to begin,
layoutSubviews gets called three times. I have break-pointed my own calls to
setNeedsLayout so I know it isn't me causing this. When
layoutSubviews looks at its bounds rectangle, it is already set to the new (rotated) width and height. So by the time my frame-setting code gets invoked as part of the rotation transition,
layoutSubviews has already positioned the views appropriately.
I can't remove
layoutSubviews because I need it for the initial configuration of the view and for my various state changes that happen while the user interacts with the app. I could rename it
myLayoutSubviews and call it explicitly as needed (in
viewDidLoad and when making state changes) but that seems like bad form.
So the question is: how do I keep
layoutSubviews from being called or how do I detect that it is being called as a result of rotation and do so in a way that feels "right"? Certainly there is a right way to do this; I just can't find it.