0

As this configuration is not supported I was wondering what alternatives people have used.

I have a universal app which currently uses a 4 tab UITabBarController on both the iPhone and iPad.

As I'd now like to use the splitviewcontroller I am faced with a design decision.

I guess I could just go with a toolbar at the top and go from there but was hoping there were more interesting techniques.

iOSDevil
  • 1,786
  • 3
  • 16
  • 29
  • 1
    possible duplicate of [Migrating a tab bar-based iPhone project to iPad ](http://stackoverflow.com/questions/3553454/migrating-a-tab-bar-based-iphone-project-to-ipad) – Shaggy Frog Dec 24 '10 at 09:45
  • It is possible to nest UISplitViewControllers in a UITabBarController. There are a few workaround necessary however. See my answer. – Brody Robertson Mar 28 '13 at 15:41

2 Answers2

0

I created a UITabBarController subclass which properly propagates the rotation messages to all UISplitViewControllers it contains. This maintains the correct internal state of the UISplitViewControllers. However, one of the SplitViewController delegate methods is not called if the SplitViewController is not visible, so I account for this in the detail view controller viewWillAppear method. I've confirmed this works in iOS5.0 - iOS6.1

AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];

    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        OSMasterViewController *masterViewController = [[[OSMasterViewController alloc] initWithNibName:@"OSMasterViewController_iPhone" bundle:nil] autorelease];
        self.navigationController = [[[UINavigationController alloc] initWithRootViewController:masterViewController] autorelease];
        self.window.rootViewController = self.navigationController;

    } else {

        OSMasterViewController *masterViewController = [[[OSMasterViewController alloc] initWithNibName:@"OSMasterViewController_iPad" bundle:nil] autorelease];
        UINavigationController *masterNavigationController = [[[UINavigationController alloc] initWithRootViewController:masterViewController] autorelease];

        OSDetailViewController *detailViewController = [[[OSDetailViewController alloc] initWithNibName:@"OSDetailViewController_iPad" bundle:nil] autorelease];
        UINavigationController *detailNavigationController = [[[UINavigationController alloc] initWithRootViewController:detailViewController] autorelease];

        masterViewController.detailViewController = detailViewController;

        UISplitViewController *splitViewController = [[[OSSplitViewController alloc] init] autorelease];
        splitViewController.viewControllers = @[masterNavigationController, detailNavigationController];
        splitViewController.delegate = detailViewController;

        OSTestViewController *secondaryController = [[[OSTestViewController alloc] init] autorelease];

        OSTabBarController *tabBarController = [[[OSTabBarController alloc] init] autorelease];
        tabBarController.viewControllers = @[self.splitViewController, secondaryController];

        self.window.rootViewController = tabBarController;
    }

    [self.window makeKeyAndVisible];
    return YES;
}

OSTabBarController.m

#import "OSTabBarController.h"

@implementation OSTabBarController

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
    for(UIViewController *targetController in self.viewControllers){
        if(targetController != self.selectedViewController && [targetController isKindOfClass:[UISplitViewController class]]){
            [targetController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
        }
    }
}

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
    for(UIViewController *targetController in self.viewControllers){
        if(targetController != self.selectedViewController && [targetController isKindOfClass:[UISplitViewController class]]){
            [targetController didRotateFromInterfaceOrientation:fromInterfaceOrientation];
        }
    }
}

@end

DetailViewController

@implementation OSDetailViewController

-(void)viewWillAppear:(BOOL)animated{
    //the splitViewController:willHideViewController:withBarButtonItem:forPopoverController: may not have been called
    if(!UIInterfaceOrientationIsPortrait(self.interfaceOrientation)){
        self.navigationItem.leftBarButtonItem = nil;
    }
}

#pragma mark - UISplitViewControllerDelegate Methods

- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController
{
    [self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];

}

- (void)splitViewController:(UISplitViewController *)splitController willShowViewController:(UIViewController *)viewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
    [self.navigationItem setLeftBarButtonItem:nil animated:YES];
}

@end
Brody Robertson
  • 8,506
  • 2
  • 47
  • 42
0

You could replicate a UITabBar within a modelViewController that pops up when a button on the bottom of the screen is taped and swap Views. :)