Jivko Dimitrov
Jivko Dimitrov

Reputation: 41

UISplitViewController in Swift navigation from DetailView

I'm trying to create a MasterDetail Application in Swift and it's running well on iOS8 Simulator. However, when I tried it on my iOS 7.1 iPad I got this error:

**Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-    [UISplitViewController displayModeButtonItem]: unrecognized selector sent to instance**

This is in my AppDelegate.swift file(generated by Xcode, I didn't add anything):

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Override point for customization after application launch.
    let splitViewController = self.window!.rootViewController as UISplitViewController
    let navigationController = splitViewController.viewControllers[splitViewController.viewControllers.count-1] as UINavigationController
    navigationController.topViewController.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem()
    splitViewController.delegate = self

    let masterNavigationController = splitViewController.viewControllers[0] as UINavigationController
    let controller = masterNavigationController.topViewController as MasterViewController
    controller.managedObjectContext = self.managedObjectContext
    return true
}

The problem comes from this line where the left button is created:

navigationController.topViewController.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem()

When I remove this line, it runs on iOS 7 but displays only the DetailView. When I swipe from the left edge the MasterView doesn't appear(on iOS 8 simulator it does) and basically there is no navigation to the MasterView

Had anyone have the same problem?

Thank you!

Upvotes: 4

Views: 1212

Answers (2)

hufeng03
hufeng03

Reputation: 404

You can still use deprecated callback function in UISplitViewControllerDelegate to add and remove UIBarButtonItem to your detail view for IOS7 platform. Implement as below in your UISplitViewControllerDelegate

func splitViewController(svc: UISplitViewController, willHideViewController aViewController: UIViewController, withBarButtonItem barButtonItem: UIBarButtonItem, forPopoverController pc: UIPopoverController) {
    if !self.respondsToSelector(Selector("displayModeButtonItem")) {
        let navigationController = self.viewControllers.last as! UINavigationController
        let detailViewController: UIViewController? = navigationController.viewControllers?.last as? UIViewController
        barButtonItem.image = UIImage(named: "IC_BackArrow")
        detailViewController?.navigationItem.leftBarButtonItem = barButtonItem
    } else {
        // This callback function is depreciated in IOS8. We use displayModeButtonItem.
    }
}

func splitViewController(svc: UISplitViewController, willShowViewController aViewController: UIViewController, invalidatingBarButtonItem barButtonItem: UIBarButtonItem) {
    if !self.respondsToSelector(Selector("displayModeButtonItem")) {
        let navigationController = self.viewControllers.last as! UINavigationController
        let detailViewController: UIViewController? = navigationController.viewControllers?.last as? UIViewController
        detailViewController?.navigationItem.leftBarButtonItem = nil
    } else {
        // This callback function is depreciated in IOS8. We use displayModeButtonItem.
    }
}

Upvotes: 2

Conrad Rowlands
Conrad Rowlands

Reputation: 11

I had the same issue. displayModeButtonItem is not supported by IOS versions prior to IOS 8. I suspect that you are compiling against IOS 8 but when deploying you are deploying onto an Ipad app with IOS 7.1 installed. I have remedied this situation in my situation (because I can) by installing IOS 8 on the target Ipad. It then worked without issue.

Upvotes: 0

Related Questions