UISplitViewController showing detail view controller first on iPhone, also delegate not calling proper functions

Hello,


In my already compelx storyboarded app, I added a Split View Controller from the Objects Library that comes with the master controller (TableViewController embedded in NavigationController) and the detail controller (ViewController) already attached to the split view controller.


On iPad, these work fine. The master controller shows up on the left as a small table view, and the detail shows up on the right as just a blank view controller. But on iPhone, upon presenting the split viewcontroller, the detail view controller shows up first, and you have to hit the back button at the top of the screen to get to the master controller. This is obviously not working right. So I searched the internet for an answer and found that you need to attack the SplitViewController to a class which has the UISplitViewControllerDelegate set to it, and return true in the function 'splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController:UIViewController, onto primaryViewController:UIViewController) -> Bool'.

So I did this exactly as the Stack Overflow answer said, and it didn't work. Just to see if it was being called, I put a log statment in the function. Upon running my app and searching for the log statement in the console, I found it wasn't there. I then created a temporary test project of the master-detail type in Xcode. I found that the AppDelegate had the UISplitViewControllerDelegate attached to it, and had that function in there like this:

func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController:UIViewController, onto primaryViewController:UIViewController) -> Bool {
        guard let secondaryAsNavController = secondaryViewController as? UINavigationController else { return false }
        guard let topAsDetailController = secondaryAsNavController.topViewController as? DetailViewController else { return false }
        if topAsDetailController.detailItem == nil {
            // Return true to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded.
            return true
        }
        return false

I tried copying this exact function over to my project in the AppDelegate and adding the UISplitViewControllerDelegate to my AppDelegate (as well as removing the function from the file attached to my UISplitViewController in the storyboard), but it didn't work because it had that detailItem thing in it. My app doesn't have that and I didn't want to add it, so I just replaced all the code in that function with this:


func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController:UIViewController, onto primaryViewController:UIViewController) -> Bool {
        NSLog("Trying to collapse secondary view controller!")
        return true
    }


Now I ran my app. It still didn't work on iPhone, but worked on iPad fine again. I looked through the log for this NSLog statment, and it wasn't there. It appears that this function isn't being called, which is preventing my UISplitViewController from being fixed through this function.


Does anyone know why this is happening? Thanks in advance. Any help is greatly appreciated.

Accepted Reply

Actually I just found out why it wasn't working.

Upon looking through the Apple Developer Resources, I found that there is a parameter to set the preferred display mode. I set that to .allVisible. It immediately worked. Apparently this one line of code calls that function when it needs to be called on iPhone. Thank you for the help anyway though!

Replies

Don't know if that will help.


In Stanford Course (Developing for IOS), there is a detailed explanation of how to make splitViews work for all types of device or all orientation. By embedding the master and detail in a navigation controller


It is lesson

7. Multiple MVCs, Timer, and Animation


I'm looking where it is in the lesson.

Look at minutes 12' to 15'

And then @ 25'

Actually I just found out why it wasn't working.

Upon looking through the Apple Developer Resources, I found that there is a parameter to set the preferred display mode. I set that to .allVisible. It immediately worked. Apparently this one line of code calls that function when it needs to be called on iPhone. Thank you for the help anyway though!