1

I'm using a splitViewController to display a master view and a detail view.

enter image description here

When I tap on a row, the detail view updates correctly.

Then, when I'm in portrait view, I collapse the splitview detail view, so that that master list items are shown as follows: enter image description here

And when I tap on a row, I correctly move to the detail view, as shown: enter image description here

The problem I'm having is that if I rotate the device in the detail view shown above, while I'm in the detail view, the rotation correctly goes back to the splitView, however, now when I select a row, the delegate method does not update the detail view. It only seems to work if I start out in the splitView and stay in that view, or if I start out in the collapsed view and stay in that. If I rotate, then the delegate method does not seem to work.

enter image description here

I found a prior post, which shows how to use the delegate method to update the detail view using objective C code, using the didSelectRow function. I tried to duplicate this code with the following swift code:

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    let navigationVC = UINavigationController()
    var detailVC = TestsDetailAdvertVC()

    if let tests = controller.fetchedObjects, tests.count > 0 {
        //if there is, keep track of the test which is selected
        selectedTest = tests[indexPath.row]

        if let isCollapsed = splitViewController?.isCollapsed {
            if isCollapsed {
                //solves problem of navigating to the detail view in compact view
                // on the iPhone (compact) the split view controller is collapsed
                // therefore we need to create the navigation controller and detail controller
                detailVC = self.storyboard!.instantiateViewController(withIdentifier: "detailVC") as! TestsDetailAdvertVC
                navigationVC.setViewControllers([detailVC], animated: false)
                self.splitViewController?.showDetailViewController(detailVC, sender: self)
                detailVC.testToEdit = selectedTest

            } else {
                // if the split view controller shows the detail view already there is no need to create the controllers
                // so we just pass the correct test using the delegate
                // if the test variable is set, then it calls the showDetail function

              delegate?.testToEdit = selectedTest
            }

        }
    }
}

I think that somehow when the one or the other method is used to update the detail view it works, but then when it switches back and forth, it stops working. I wonder if anyone has solved this issue using swift code who could point me to an example.

Note: After some additional searching, I realized that there are a few of delegate methods for the splitViewController, including:

func primaryViewControllerForExpandingSplitViewController:

and

func primaryViewControllerForCollapsingSplitViewController:

and

splitViewController:separateSecondaryViewControllerFromPrimaryViewController:

I've been fiddling around with these methods, but so far haven't been able to get them to work, and I haven't found any posts that show examples of how they are used.

Thanks.

user3284547
  • 105
  • 2
  • 11
  • Try Xcode's Master Detail app template and see how it works, look at the storyboard closely for how to use the adaptive segues. There is no need to check for collapsed state its all automatic. – malhal Jan 10 '19 at 00:01

1 Answers1

0

I figured out how to make the detail view update properly, using an answer from a prior post at:

In UISplitViewController, can't make showDetailViewController:sender: push onto detail navigationController

my code to solve the problem is updated using swift code:

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    var detail = UINavigationController()
    var testVC = TestsDetailAdvertVC()

    if let tests = controller.fetchedObjects, tests.count > 0 {
        //if there is, keep track of the test which is selected
        selectedTest = tests[indexPath.row]

        if let isCollapsed = splitViewController?.isCollapsed {
            if isCollapsed {
                //in collapsed view, the correct detail view controller is not
                //yet substantiated, so we need to substantiate it
                testVC = self.storyboard?.instantiateViewController(withIdentifier: "detailVC") as! TestsDetailAdvertVC
                detail.setViewControllers([testVC], animated: true)
                testVC.testToEdit = selectedTest

            } else {
                //in expanded view, the correct view controller needs
                //to be identified, using the appropriate view controller for
                //the splitview controller
                let vc = self.splitViewController?.viewControllers[1]
                //which is a navigation controller
                if vc is UINavigationController {
                    detail = vc as! UINavigationController
                    //which we then use to identify the correct detail view
                    testVC = detail.viewControllers.first as! TestsDetailAdvertVC
                    testVC.testToEdit = selectedTest
                }
            }
        }
    }
    self.splitViewController?.showDetailViewController(detail, sender: self)
}

The key solution is that on the collapsed splitviewcontroller, the detail view has to be instantiated form the storyboard. However, on the expanded splitviewcontroller, the detail view has to come from the expanded navigation controller. Then when I rotate the correct detail view controller updates correctly.

user3284547
  • 105
  • 2
  • 11