views:

87

answers:

2

I have a iPad application which goes between two states, one using a SplitView the other a TableView.

Currently I have a single UIWindow object, and switch between views with the following code

-(void) switchToStateA {
[viewControllerB.view removeFromSuperview];
[window addSubview:viewControllerA.view];
}
-(void) switchToStateB {
[viewControllerA.view removeFromSuperview];
[window viewControllerB.view];
}

Everything works fine unless I change the device orientation. After changing orientation and switching states, the state which was not active during the change is still in the frame of its old state (leaving black areas at the edge of the display). If I change the orientation again the new state will be fixed.

I've tried adding

[viewControllerA.view setNeedsLayout];

after swapping the views but it did not have an effect.

How do I make sure the background view controllers get the orientation callback, or how do I invoke a 'refresh' when I switch state?

+1  A: 

This is pure speculation on my part, but what if instead of removing the view controller's view from the window, you set the view to hidden and use exchangeSubviewAtIndex:withSubviewAtIndex: to change which view controller's view is visible to the user. I wonder if the OS is optimizing not sending rotation events to any view controllers whose views don't have a super view.

You could even get fancy with animations and fade the top view's alpha to 0 while the bottom view's alpha fades to 1 before they switch places.

Robot K
Thanks, I'll give that a try. Although I had a serious problem when the UIWindow contained multiple subviews everything seemed to just fall apart.
Akusete
As soon as I insert multiple views into the UIWindow using (addSubview:) _none_ of the views recieve any rotation callbacks, and the screen appears very buggy when I try and rotate.
Akusete
I hadn't thought about that. You may need to create a "content view" inside your window and put the view controller's views into that. Of course, now you're creating a pretty deep view hierarchy, which may have perf or memory implications.
Robot K
A: 

Device orientation changes are handled by UIViewControllers, not by isolated UIViews. The easiest way to solve your problem is to make the controller's view a dumb container, which you never remove from the window. The container view will always be correctly rotated as permitted by the controller. Then you just add/remove subviews to/from the container view to get them rotated too. Don't forget to set subviews' frames and autoresizing masks before adding them to the container view.

Costique
I dont understand why the 'dummy' container is needed, since the UIWindow is a view itself.
Akusete
I think your suggestion about settings the subviews frame will work, Unfortunately I dont know how to do that for the SplitView
Akusete
UIWindow is just a view, but a very special kind of it. It tracks the first view controller whose view is added to it and sends it device rotation messages. It does not send those messages directly to views. That's why you need a "root" view controller which will get the messages. You can do anything with it, including adding/removing split views and table views to the controller's view, just like you add them to a window. If, however, you are swapping view controllers, you can create a root UINavigationController and send it -setViewControllers: to swap them.
Costique