开发者

UISplitViewController strange behavior

开发者 https://www.devze.com 2023-01-08 11:16 出处:网络
Hi i have a splitViewController mapViewController = [[MapViewController alloc] initWithManagedObjectContext:managedObjectContext startingRegion:startingRegion];

Hi i have a splitViewController

mapViewController = [[MapViewController alloc] initWithManagedObjectContext:managedObjectContext startingRegion:startingRegion];

    distanceViewController = [[DistanceTableViewController alloc] initWithManagedObjectContext:managedObjectContext];
    distanceViewController.mapViewController = mapViewController;
    setupViewController = [[SetupTableViewController alloc] initWithStyle:开发者_如何学运维UITableViewStyleGrouped map:mapViewController.map];   
    setupViewController.positionSwitch.on = savePosition;

    SearchTableViewController *searchViewController = [[SearchTableViewController alloc]  initWithStyle:UITableViewStylePlain managedObjectContext:managedObjectContext];   
    searchViewController.mapViewController = mapViewController;

    tabBarController = [[UITabBarController alloc] init];

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
    {
        UINavigationController *mapNavigationController = [[[UINavigationController alloc] initWithRootViewController:mapViewController] autorelease];
        UINavigationController *searchNavigationController = [[[UINavigationController alloc] initWithRootViewController:searchViewController] autorelease];
        UINavigationController *distanceNavigationController = [[[UINavigationController alloc] initWithRootViewController:distanceViewController] autorelease];
        UINavigationController *setupNavigationController = [[[UINavigationController alloc] initWithRootViewController:setupViewController] autorelease];

        UISplitViewController* splitVC = [[UISplitViewController alloc] init];
        splitVC.viewControllers = [NSArray arrayWithObjects:searchNavigationController, mapNavigationController, nil];
        splitVC.title = @"iMetano";
        splitVC.tabBarItem = [[[UITabBarItem alloc] initWithTitle:@"Mappa" image:[UIImage imageNamed:@"mapIcon2.png"] tag:0] autorelease];

        NSArray *viewControllersArray = [NSArray arrayWithObjects: splitVC,setupNavigationController,nil];
        [splitVC release];

        tabBarController.viewControllers = viewControllersArray;
    }

When i startup my app in portrait, all works fine.

When i startup my app in landscape this is the result

UISplitViewController strange behavior

  1. I see only the view of the first viewController SearchTableViewController with some pixel between the UINavigationController and the status bar
  2. When i rotate in portrait and after i return in landscape i see both viewController's view, but the second have some pixel between the statusBar and the UINavigationControllor

I can't understand why.


apple says not to put a split view controller inside something else, like a tab bar controller


After looking at my code and IB time after time. This is the best that I could come up with. Not sure if is the best one but it works for me. Im loading a default detail view controller. If I load the controller directly in the viewDidLoad then the problem occur. If I load it from the selector the problem goes away. I hope this helps. I have this code in the RootViewController.

    - (void)viewDidLoad {
        [super viewDidLoad];
        [self performSelector:@selector(loadController) withObject:nil afterDelay:0];
    }

    -(void)loadController{
    UIViewController <SubstitutableDetailViewController> *detailViewController = nil;
    WebViewController *newDetailViewController = [[WebViewController alloc] initWithNibName:@"WebViewController" bundle:nil];
    [newDetailViewController setTitle:@"Home"];
    NewNavController <SubstitutableDetailViewController>*navController = [[NewNavController alloc] initWithRootViewController:newDetailViewController];

    detailViewController = navController;

    NSArray *viewControllers = [[NSArray alloc] initWithObjects:self.navigationController, detailViewController, nil];
    splitViewController.viewControllers = viewControllers;


}


I had this exact same problem when attempting the combination of tab bar, split view and navigation controllers. I noticed that the alignment gap is only present when the application first fires up and the first tab is auto-selected because it's the first tab in the tab bar controller's array of view controllers. After switching tabs and then coming back to the one with the misaligned nav controller in a split view, there was no alignment problem present. So, to replicate this behavior and get rid of the misalignment when the screen is first rendered I added:

[tabBarController setSelectedViewController:splitVC];

right after setting the view controller array on the tab bar controller. Works like a champ now.


I know this is an old question, but here's the hack I just used to get around this problem for anyone who has a navigation hierarchy like mine:

UITabBarController
    Tab0->UINavigationController->MGSplitViewController _or_ UISplitViewController
    Tab1->UINavigationController->SomeOtherViewController
    Tab2->Etc...

Nothing I tried could get rid of that 20px gap that occurs only once, at bootup, if the device orientation is anything except UIInterfaceOrientationPortrait. The 20px gap is caused by the UINavigationBar for the split view's UINavigationController above having a non-zero origin.y value; most likely, you'll find it to be 20.

Also, I found that this is only a problem if the device is running iOS < 5.0.

I check for this issue in the view controller code of my MGSplitViewController (i.e. self = an MGSplitViewController):

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    if(self.doIOS4OneTimeRotationHack == YES)
    {
        self.doIOS4OneTimeRotationHack = NO;
        for(UINavigationController *navController in [self viewControllers])
        {
            if(navController.navigationBar.frame.origin.y != 0.0f)
            {
                [UIView animateWithDuration:0.01
                                      delay:0.0
                                    options:UIViewAnimationOptionCurveEaseOut
                                 animations:
                 ^(void)
                 {
                     navController.navigationBar.frame = CGRectMake(navController.navigationBar.frame.origin.x,0.0f, navController.navigationBar.frame.size.width,navController.navigationBar.frame.size.height);
                 }
                                 completion:
                 ^(BOOL finished)
                 {
                     //NSLog(@"Shifted navbar 0x%x up!",navController.navigationBar);
                 }];
            }
        }
    }
}

With the animation set to finish in just 0.01 seconds, it happens so fast that you'll never even notice it as your bootup splash screen disappears and your MGSplitViewController view appears in its place. Maybe play around with it and make it instantaneous; I had to get it working and move onto my next task, so I didn't fool with it past that point.

I don't like resorting to hacks like this, but this was the only way I was able to get around this problem. ScottS' solution below sounded great, but unfortunately didn't work for me.

0

精彩评论

暂无评论...
验证码 换一张
取 消