Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Having a UINavigationController in the master view of a UISplitViewController in iOS 8

In my UISplitViewController, the master view is a UINavigationController containing a UITableViewController. Sometime, when the user selects an item in the table, I have to push another UITableViewController over the existing table in the master view.

In iOS 7, inside my first UITableViewController I just call

[self.navigationController pushViewController:otherTableVC animated:YES];

In iOS 8:

When the split view is collapsed, the otherTableVC becomes the detail View! Then after rotating the device, we see the two tables side by side...

Worse, if the device shows the two panes, the code works great and the second table is pushed over the first one in the master view. But, after a double rotation, the two tables are again side by side. It seems the collapsed mode of the UISplitViewController interferes with my own navigation controller…

How can I manage my own UINavigationController in the Master View?

Thank you

EDITED:

My both primary and details views have a navigation Controller. And to solve my problem, I just discovered that, in collapsed mode, I have to create an extra Navigation Controller and push it over the primary navigation controller.

UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:otherTableVC];
[self.navigationController pushViewController:navController animated:YES];

So I just discovered hat we can push a navigation Controller inside another Navigation Controller.

like image 554
PatrickV Avatar asked Sep 26 '14 13:09

PatrickV


1 Answers

Swift 4 Version with minor changes to make it work with my code:

func splitViewController(_ splitViewController: UISplitViewController, showDetail vc: UIViewController, sender: Any?) -> Bool {
    if !isCollapsed {
        // in expanded mode set new VC as top view controller of the detail nav controller
        if let detailNavigationController = viewControllers[1] as? UINavigationController {
           detailNavigationController.setViewControllers([vc], animated: false)
        }
    } else {
        // in collapsed mode push the new view controller on the master nav controller
        if let masterNavigationController = viewControllers[0] as? UINavigationController {
            masterNavigationController.pushViewController(vc, animated: true)
        }
    }
    return true
}

func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {

    let masterNavigationController = primaryViewController as? UINavigationController
    let detailNavigationController = secondaryViewController as? UINavigationController
    let episodeDetailViewController = detailNavigationController?.viewControllers.first as? EpisodeDetailTableViewController
    if episodeDetailViewController?.episode == nil {
        // detail view is blank. We do not need to push this onto the master
        return true
    }

    guard var newMasterViewControllers = masterNavigationController?.viewControllers else { return false }
    newMasterViewControllers.append(contentsOf: detailNavigationController?.viewControllers ?? [])
    masterNavigationController?.setViewControllers(newMasterViewControllers, animated: false)
    return true
}


func splitViewController(_ splitViewController: UISplitViewController, separateSecondaryFrom primaryViewController: UIViewController) -> UIViewController? {
    let masterNavigationViewController = primaryViewController as? UINavigationController

    var newMasterViewControllers = [UIViewController]()
    var newDetailViewControllers = [UIViewController]()

    for vc in masterNavigationViewController?.viewControllers ?? [] {
        if vc is PodcastsTableViewController || vc is EpisodesTableViewController {
            newMasterViewControllers.append(vc)
        } else {
            newDetailViewControllers.append(vc)
        }
    }

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let detailNavigationController = storyboard.instantiateViewController(withIdentifier: "splitViewDetailViewController") as! UINavigationController

    if newDetailViewControllers.count == 0 {
        let emptyEpisodeDetailViewController = storyboard.instantiateViewController(withIdentifier: "episodeDetail")
        newDetailViewControllers.append(emptyEpisodeDetailViewController)
    }

    masterNavigationViewController?.setViewControllers(newMasterViewControllers, animated: false)
    detailNavigationController.setViewControllers(newDetailViewControllers, animated: false)
    return detailNavigationController
}
like image 66
funkenstrahlen Avatar answered Sep 19 '22 04:09

funkenstrahlen