Search code examples
iosswiftxcode-storyboard

Segue to DetailViewController (SplitViewController)


I'm having a hard time selecting the view controller that show be the detail view in the split view controller. It appears that there is some default caller to the view controller behind showDetail but I cannot find where. When the split view controller loads, it show DetailViewController as the detail in split of my attempts to set it to OverviewViewController. The showDetail segue is not called on load, however it is still the default.

When I have overrided the didSelectRowAtIndexPath on the master, I see a flicker as it sets the DetailViewController briefly before setting OverviewViewController.

Here is my code:

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    self.navigationItem.leftBarButtonItem = self.editButtonItem()
    if let split = self.splitViewController {
        let controllers = split.viewControllers
        self.detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? OverviewViewController

    }
}

// MARK: - Segues
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    print("did select row")
    NSOperationQueue.mainQueue().addOperationWithBlock {
        self.performSegueWithIdentifier("showOverview", sender: self)
    }

}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "showDetail" {
        print("segue to showDetail")
            let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController
            controller.injectOrder(gobl_meal_orders[indexPath.row])
            controller.detailItem = object
            controller.navigationItem.leftBarButtonItem = self.splitViewController?.displayModeButtonItem()
            controller.navigationItem.leftItemsSupplementBackButton = true
        }
    }else if segue.identifier == "showOverview"{
        print("show overview called")
    }
}

Where is this hidden preselection of view controller?


Solution

  • If I understand correctly, you don't want the detail view to be displayed when your splitview controller is loaded.

    The way to control this is to use a custom class for your UISplitViewController and implement the following delegate method

    splitViewController(_:collapseSecondaryViewController:ontoPrimaryViewController:)

    Here is an example.

    import UIKit
    
    class MyCircleUISplitViewController: UISplitViewController, UISplitViewControllerDelegate {
    
      override func viewDidLoad() {
        super.viewDidLoad()
        delegate = self
    
        // Do any additional setup after loading the view.
      }
    
      override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
      }
    
      func splitViewController(splitViewController: UISplitViewController, collapseSecondaryViewController secondaryViewController: UIViewController, ontoPrimaryViewController primaryViewController: UIViewController) -> Bool {
        return true
      }      
    }
    

    Here is also a nice blog on UISplitViewControllers that you might find interesting.