I have recently run into an issue when porting some code from an iPhone app over to the iPad. It may be related to the issue described here, though I found the explanations/solutions of that question unsatisfactory. The scenario is this:
View controller 'A' (The Root View Controller) presents a modal view controller (call it 'B') with the "Form Sheet" modal presentation style.
View controller B presents view controller 'C' with the "Full Screen" modal presentation style.
The iPad is rotated while view controller C is the top-most presented view controller.
Upon dismissal of C, B is re-displayed, but has the incorrect orientation.
As far as I can tell, there should not be an issue with chaining of multiple presented view controllers -- in fact, this behavior is explicitly supported in the Presenting View Controllers from Other View Controllers documentation. I have also read the following statement in the iOS 5 Release Notes:
Rotation callbacks in iOS 5 are not applied to view controllers that are presented over a full screen. What this means is that if your code presents a view controller over another view controller, and then the user subsequently rotates the device to a different orientation, upon dismissal, the underlying controller (i.e. presenting controller) will not receive any rotation callbacks. Note however that the presenting controller will receive a viewWillLayoutSubviews call when it is redisplayed, and the interfaceOrientation property can be queried from this method and used to lay out the controller correctly.
As far as I can tell, this does not occur -- View controller B receives a call to -shouldAutoRotateToInterfaceOrientation but the value the interfaceOrientation parameter in this call is the value of view controller B's interface orientation when it presented view controller C, not the value of C's interface orientation upon dismissal. Since we're on an iPad, all these view controllers return YES in -shouldAutoRotateToInterfaceOrientation. Thus the bounds of B's view never change, so -willLayoutSubviews is never called.
I have tried saving the orientation of view controller C in a callback to B before B dismisses it, and then using that information the next time -shouldAutoRotateToInterfaceOrientation is called and returning YES only for the orientation of C when it is dismissed. This fixes, the broken UI that appears without making this check, but view controller B does not update its interface orientation to this value, so subsequent modal presentations will animate in/out from the wrong side of the device.
Has anyone been able to successfully get a view controller configuration like this working? It doesn't seem like that unusual of a scenario, so I am a little surprised that it isn't working as I initially expected it to.
Thanks in advance.