8

On iOS 13 Beta 5, I currently have problems with my UISplitView on iPhones.

My app starts with the detailsview off my splitview not with my masterview (look at the picture) detailview

Does anyone know how i can fixed this problem under iOS 13? On iOS 12 everything works like a charm ☹️

Thx in advance Sebastian


Edit:

Sorry for the late answer I was on a short holiday trip without any internet :/

my Class looks like this:


class MyClass : UITableViewController, UISplitViewControllerDelegate, UIPickerViewDelegate {

override func viewDidLoad() {
        super.viewDidLoad()

        if (UIDevice.current.userInterfaceIdiom == .pad){
            navigationController?.navigationBar.isTranslucent = false
        }

        /*SplitView*/

        splitViewController?.preferredDisplayMode = .allVisible
        splitViewController?.delegate = self

        self.definesPresentationContext = true

}

    // SplitView
    func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {
        return true
    }

}


I think it's look like the normal procedure for this problem :/

Sebastian R.
  • 447
  • 8
  • 21
  • You haven't told us what you were doing on iOS 12. (You haven't told us _anything_ really.) The UISplitViewController's delegate has to be configured to show the master view instead of the detail view. Show us how you're doing that. – matt Aug 04 '19 at 19:36
  • i edit my question – Sebastian R. Aug 07 '19 at 15:14
  • I'm having the same problem with my split views. Always starts in the detail view on an iPhone (X in my case). Also my UISplitViewController delegate methods are not being called, despite setting the delegate to my view controller in viewDidLoad. Did you ever solve this problem? – Tap Forms Aug 11 '19 at 20:06
  • Nope I didn’t solved the problem at the moment :/ – Sebastian R. Aug 11 '19 at 20:11
  • 1
    Same here. Also started from Beta 5 (or, at least, haven't seen it prior that). Happens every once in a while - maybe once a day. – Konstantin Loginov Aug 15 '19 at 12:44
  • What you're doing was always wrong. I'm surprised it worked on iOS 12. The delegate must be set on the split view controller the moment it is created, not at some later time. – matt Sep 07 '19 at 22:40

8 Answers8

10

I had the same issue.

After a bit of investigation it seems like viewDidLoad is too late to set it to all visible.

I subclassed the UISplitViewController and changed the setting in awakeFromNib method. Now it is working as expected.

alxlives
  • 5,084
  • 4
  • 28
  • 50
6

Alxlives's answer helped me. By using the debugger, I notice that in the master view controller, viewDidLoad is not called. So the delegate is never set, thus the collapse method is never called.

I fixed this by setting the delegate in awakeFromNib():

override func awakeFromNib() {
    self.splitViewController?.delegate = self
}

Now the splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool is called, and if you return true, the master will be displayed.

Chris Slade
  • 8,077
  • 1
  • 16
  • 13
  • 1
    To say that `viewDidLoad` is not called is misleading. `viewDidLoad` is _always_ called at the proper time. If you had some misconfiguration, it lies elsewhere. – matt Sep 07 '19 at 22:42
4

Warren Milward's answer helped me to guide me in the right direction, but actually I got it working with viewDidLoad().

I ended up using a subclass for the UISplitViewController and set the required values in viewDidLoad() as well as the delegate calls here.

class CustomSplitViewController: UISplitViewController, UISplitViewControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        self.delegate = self
        self.preferredDisplayMode = .allVisible
    }

    func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {
        return true
    }
}
alexkaessner
  • 1,966
  • 1
  • 14
  • 39
2

did you try this one (UISplitViewControllerDelegate):

self.preferredDisplayMode = .allVisible

&

func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {
    return true;
}
тσм.
  • 21
  • 2
0

Try MasterViewController_Instance.view.layoutIfNeeded() inside Splitviewcontroller ViewDidLoad() method. It fixed my problem.

class CustomSplitController: UISplitViewController{ 
    override public func viewDidLoad() {

        MASTER_CONTROLLER_INSTANCE.view.layoutIfNeeded()
        //If you are using navigation controller in master controller try 
        MASTER_CONTROLLER_INSTANCE.navigationController?.view.layoutIfNeeded()
    }
}
barbsan
  • 3,418
  • 11
  • 21
  • 28
0

I set the spliteViewController's delegate on appdelegate, and it worked

0

For those who use storyboard and configure the new controller in a subclass from UIStoryboardSegue, it'll be simpler:

just before [source presentViewController:destination animated:YES completion:nil];, just set destination.modalPresentationStyle = UIModalPresentationFullScreen;, because the default is now UIModalPresentationPageSheet.

tontonCD
  • 320
  • 2
  • 6
-1

As many answers here leads to change in the Split View Controller starting sequence, I realized, that on compact size it performs vewDidLoad on detail controller ONLY. But awakeFromNib is called on every controller. So - I've just transfer my code from viewDidLoad to awakeFromNib and everything now is works perfectly!

override func awakeFromNib() {
    super.awakeFromNib()

    if let splitController = splitViewController {
        splitController.delegate = self
    }
}
Andy G
  • 129
  • 2
  • 4