Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Master-Detail application template from xCode 6 doesn't run on iOS 7

I'm trying to develop a master-detail iOS application (iPad only) from the xCode 6 template. It runs fine with iOS 8 but running it on iOS 7.0 or 7.1 produces a crash at run-time where I've commented:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
    UINavigationController *navigationController = [splitViewController.viewControllers lastObject];

    // this line throws a "[MasterViewController topViewController]: unrecognized selector sent to instance 0x796dde90"
    navigationController.topViewController.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem;
    splitViewController.delegate = self;
    return YES;
}

To reproduce the bug :

  • Open xCode 6
  • File > New > Project
  • Choose "Master-Details Application" below "iOS application"
  • Change target of the project to 7.0
  • Run on emulator or device

I investigated and it seems that object types differs on iOS 7 and iOS 8:

  • On iOS8, self.window.rootViewController is a UISplitViewController
  • On iOS7, self.window.rootViewController is the first UINavigationController (left)

Why this behavior?

like image 328
Greg M. Avatar asked Nov 06 '14 09:11

Greg M.


2 Answers

Put this under prepareForSegue: to ensure backwards compatibility.

DetailViewController *controller;
    if ([[segue destinationViewController] isKindOfClass:[UINavigationController class]]) {
        controller = (DetailViewController *)[[segue destinationViewController] topViewController];
    }
    else {
        controller = (DetailViewController *)[segue destinationViewController];
    }
[controller setDetailItem:object];
like image 97
Offek Avatar answered Sep 21 '22 02:09

Offek


try this replacement:

if ([splitViewController respondsToSelector:@selector(displayModeButtonItem)]){
    navigationController.topViewController.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem;
}
like image 29
Jef Avatar answered Sep 21 '22 02:09

Jef