views:

152

answers:

3

I'm working on a universal iPhone/iPad application. I'm using MonoTouch, but I can take answers in Obj-C (I should be able to decipher it, and MonoTouch's UIKit is 1 to 1 for the most part).

Basically my app has 2 views: a "login" view and a "logged-in" view.

On app startup, my login view is the only subview of my main UIWindow. After logging in, I call RemoveFromSuperview on the login view and UIWindow.AddSubView to add the logged-in view. All of this works great, and orientations work also b/c I respond to ShouldAutorotateToInterfaceOrientation.

All until you logout, and the orientation starts to get all jacked up. On orientation, the app orients the status bar, but leaves my views untouched. On top of that, on the iPad my UISplitView acts very strange with my master view oriented one way and the detail view the other way.

What is the proper way to switch views in a UIWindow? I feel like the orientations should work automatically, thus I'm doing something wrong.

UPDATE:

Here is a code snippet (in C#, but you get the idea):

_loginController.View.RemoveFromSuperView();
_window.AddSubView(_loggedInController.View);

To do the reverse:

_loggedInController.View.RemoveFromSuperView();
_window.AddSubView(_loginController.View);

Fairly straightforward, right?

UPDATE 2:

I made a simple repro--even included a UISplitViewController, and it works just fine.

There must be something specific in my app that is causing this strange behavior.

A: 

If I understand this properly, you can check the view orientation before you load the new view. I think I did something almost identical. Try doing something like this:

CGRect frame = [[UIScreen mainScreen] applicationFrame];

    switch(splitViewController.interfaceOrientation){
        case UIInterfaceOrientationPortrait:
        case UIInterfaceOrientationPortraitUpsideDown:
            [splitViewController.view setFrame:frame];
            break;
        case UIInterfaceOrientationLandscapeLeft:
        case UIInterfaceOrientationLandscapeRight:
            [splitViewController.view setFrame:CGRectMake(frame.origin.x, frame.origin.y, frame.size.height, frame.size.width)];
            break;
    }

Basically get the current application frame and manually orient it. There is a bug in the splitViewController that will not check the orientation if you display it after the applicationDidFinishLaunching method is executed.

Geoff Baum
My login view doesn't have a split view, so why would it experience this issue? It's a pretty standard view with username/password and a button. Either way, I'll give this a shot.
Jonathan.Peppers
This caused similar strange issues, I was already doing this orientation work in my UISplitViewController on ViewDidAppear. I'm going to try to reproduce this with a test app, and post it up here.
Jonathan.Peppers
Check out my other answer, that may help more...
Geoff Baum
A: 

Ok I see, well I have a similar application but just approached the problem differently.

I created and initialized the splitViewController in the appDidFinishLaunching method and passed it to my login screen.

 theLoginScreen = [[LoginViewController alloc] initWithNibName:@"LoginViewController" bundle:[NSBundle mainBundle]];
    theLoginScreen.splitViewController = splitViewController;
    theLoginScreen.detailViewController = detailViewController;
    theLoginScreen.rootViewController = rootViewController;
    theLoginScreen.appDelegate = self;

    [window addSubview:theLoginScreen.view];

From here I did the login stuff and then did something like this:

[self.view removeFromSuperview];

    CGRect frame = [[UIScreen mainScreen] applicationFrame];

    switch(splitViewController.interfaceOrientation){
        case UIInterfaceOrientationPortrait:
        case UIInterfaceOrientationPortraitUpsideDown:
            [splitViewController.view setFrame:frame];
            break;
        case UIInterfaceOrientationLandscapeLeft:
        case UIInterfaceOrientationLandscapeRight:
            [splitViewController.view setFrame:CGRectMake(frame.origin.x, frame.origin.y, frame.size.height, frame.size.width)];
            break;
    }

    [appDelegate.window addSubview:splitViewController.view];

Give something like that a shot and see if that works. :)

Geoff Baum
Doesn't act any different than the other answer. Again, I'm going to make the simplest project to replicate the issue, as I believe the UISplitViewController may be causing the issue.
Jonathan.Peppers
Ok a couple of things. Your splitview loading strangely (rv right, dv wrong) should be fixed by the code above. I had the same problem, and that fixed it. Second, do you ever display anything modally? I was doing this before and it was causing the sort of status bar rotation/view stuck problem you are describing.
Geoff Baum
It had something to do with how I was displaying the modal view. The superview wasn't rotating so the modal view was stuck as well.
Geoff Baum
Yeah, I'm not displaying anything with a modal view. I have started my project over, and thus far the new project doesn't have the issue. (I was going to do this anyway to clean everything up) Another thing I have that is strange is a UITabBarController inside a UISplitViewController, but that has been working thus far in the new project.
Jonathan.Peppers
Well that's not that strange. I have put a UITabBarController inside a SVC before.
Geoff Baum
A: 

In my new project, the issue randomly started occurring (not sure what I changed to make it happen). So there must be something in my UI layout causing it.

I took a suggestion from a commenter, and took a look at modal views.

The following works great:

  • Made the SplitViewController the top level view
  • Made the login prompt view appear modally from the SVC
  • Logout functionality is: _loggedInController.PresentModalViewController(_loginController, true);
  • Login functionality is: _loggedInController.DismissModalViewControllerAnimated(true);
  • The orientation code for to fix the SVC's Frame still has to be added to ViewDidLoad

No strange orientation problems happen now.

This also give mes the benefit of a nice sliding transition without adding any code to do it.

Jonathan.Peppers