iOS Universal Application

Universal Application

Universal Application is a single binary for both iPad and iPhone. To accomodate the difference of the screen size:

  • iPhone app will depends on navigation controller to push a stack of content while
  • iPad app will use split view to display 2 views on the same screen

To determine whether the device is an iPhone

 ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)

Load different NIB for difference difference

    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        self.viewController = [[HelloNibViewController alloc] initWithNibName:@"HelloNibViewController_iPhone" bundle:nil];
    } else {
        self.viewController = [[HelloNibViewController alloc] initWithNibName:@"HelloNibViewController_iPad" bundle:nil];
    }

Create a universal application view by create different views programmatically

  • For iPhone, we use navigation controller to navigate between the first and the second view controller
  • For iPad, we use split view controller to display the first and the second view controller side by side
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
        UINavigationController *navigation = [[UINavigationController alloc] init];
        FirstViewController *vc1 = [[FirstViewController alloc] init];
        [navigation pushViewController:vc1 animated:NO];
    
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
    	UISplitViewController *split = [[UISplitViewController alloc] init];
    
    	UINavigationController *rightNavigation = [[UINavigationController alloc] init];
    	[rightNavigation pushViewController:vc1.secondViewController animated:NO];
            split.delegate = vc1.secondViewController;
    
    	split.viewControllers = [NSArray arrayWithObjects:navigation, rightNavigation, nil];
    	[window addSubview:split.view];
         } else {
    	[window addSubview:navigation.view];
         }
    
        [window makeKeyAndVisible];
    
        return YES;
    }
    

Create a First View Controller embedded within a Navigation controller

    UINavigationController *navigation = [[UINavigationController alloc] init];
    FirstViewController *vc1 = [[FirstViewController alloc] init];
    [navigation pushViewController:vc1 animated:NO];

For iPhone, use this navigation controller as a starting point in navigation

	[window addSubview:navigation.view];

For iPad, create a split controller with the right side hosting the second view

	UISplitViewController *split = [[UISplitViewController alloc] init];

	UINavigationController *rightNavigation = [[UINavigationController alloc] init];
	[rightNavigation pushViewController:vc1.secondViewController animated:NO];
        split.delegate = vc1.secondViewController;

	split.viewControllers = [NSArray arrayWithObjects:navigation, rightNavigation, nil];
	[window addSubview:split.view];
  • For a universal application, the iPhone part may use a simple navigation controller
  • To make sure the second view is not display before pushing it
    // If the display is not shown yet
    if (SomeViewController.view.window == nil) {
       [self.navigationController pushViewController:self.SecondViewController animated:YES];
    }
    
  • For a iPad, the second view may already displayed in a splited view and therefore do not need to push it