iOS 13 UISplitView Problems

2020-02-28 20:09发布

问题:

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)

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 :/

回答1:

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.



回答2:

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.



回答3:

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
    }
}


回答4:

did you try this one (UISplitViewControllerDelegate):

self.preferredDisplayMode = .allVisible

&

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


回答5:

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()
    }
}


回答6:

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
    }
}


回答7:

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



回答8:

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.