I know that this looks like a huge question but it's not so don' be afraid to read it. Mostly it's me explaining how stuff works.
I have two UIWindow
s in my app. The first one is the main window which gets created by the app by default. The second one is called modalWindow
and is also created in the app delegate.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.modalWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.modalWindow.windowLevel = UIWindowLevelStatusBar;
//Other stuff I need
//....
return YES;
}
Most of my app is portrait only but there is one view controller where the user can switch to landscape orientation. I'm listening for landscape change via:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:nil];
This works fine and in the orientationChanged
method I present the landscape view controller. All is well at this point. If I rotate back to portrait I get the orientationChanged
fired once more at which point I dismiss the landscape view controller.
Now let's explain how the second window comes into play. When in landscape mode there is an action (just a button press) which presents a new view controller on the second window (the modalWindow
). Ok let's explain this.
The app delegate has two methods which look like so:
- (void)presentActivityOnModalWindow:(UIViewController *)viewController
{
self.modalWindow.rootViewController = viewController;
self.modalWindow.hidden = NO;
}
- (void)modalTransitionFinished:(NSNotification *)notif
{
self.modalWindow.hidden = YES;
self.modalWindow.rootViewController = nil;
}
I call the presentActivityOnModalWindow
via the [[[UIApplication sharedApplication] delegate] performSelector....]
. I know it isn't the best practice but it works fine. As for the dismissal I use NSNotificationCenter
to post the notification about dismissal. The view controller that gets presented on the modalWindow
is supporting only portrait mode. It's returning YES
in shouldAutorotate
and UIInterfaceOrientationMaskPortrait
in supportedInterfaceOrientations
.
Ok a lot of explaining but now we get to the problem. When I rotate to landscape, pop up the modalWindow, dismiss the modal window and rotate back to portrait my main window is still in landscape mode and everything looks catastrophic.
I tried adding an observer to both window
and modalWindow
and logging changes in frame
and bounds
and here are the results:
Did finish launching:
window frame {{0, 0}, {320, 568}}
window bounds {{0, 0}, {320, 568}}
modalWindow frame {{0, 0}, {320, 568}}
modalWindow bounds {{0, 0}, {320, 568}}
Rotate to landscape:
window frame {{0, 0}, {568, 320}}
Open activity in landscape:
modalWindow frame {{0, 0}, {320, 568}}
modalWindow frame {{0, 0}, {320, 568}}
Dismiss activity:
none
Rotate back to portrait:
none
So as it seems my window
does not get back to normal frame when we get back to portrait mode. How to fix this? If I need to provide any more details feel free to ask.
The system will only handle rotation of your keyWindow
. If you have other windows you'll have to handle rotation yourself.
I also think that modal controllers is the way to go. But if you really want to handle rotations take a look at how other "custom windows" libraries handle rotation. Alert views are a great example:
https://github.com/search?o=desc&q=uialertview&s=stars&type=Repositories&utf8=✓
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With